/* ─── Site commercial Axeho ───
   Parti pris : LA BANDE RYTHMO COMME DISPOSITIF. Le ruban horizontal, sa ligne de départ verticale et
   son texte étiré selon le débit sont la signature du site. Il n'apparaît qu'à trois endroits — le
   héros de l'accueil, les séparateurs de section, le schéma du pipeline. Partout ailleurs : silence,
   densité, alignements stricts. On dépense l'audace à un seul endroit.

   ⚠️ Fond sombre SEULEMENT. Les captures du produit sont sombres et paraîtraient collées sur un site
   clair, et l'acheteur passe sa journée dans Cappella, Pro Tools et Resolve. */

:root {
  /* ── Jetons de la refonte ──────────────────────────────────────────────
     Les quatre couleurs de piste ne sont pas décoratives : elles encodent les familles phonétiques
     de la méthode de détection du produit. C'est ce qui distingue cette palette d'un « noir + une
     couleur acide » de série.
     ⚠️ RÈGLE STRICTE : elles n'apparaissent QUE dans le dispositif rythmo, la légende phonétique et
     les puces de service. Jamais sur un bouton, un lien ou un dégradé. */
  --encre: #141118;        /* fond — noir tirant sur le violet, pas un noir neutre */
  --pellicule: #1E1A24;    /* surfaces : cartes, panneaux */
  --regie: #2C2833;        /* bordures, filets, séparateurs */
  --craie: #EDE7E3;        /* texte principal — blanc chaud : la rythmo s'écrivait à l'encre blanche */
  --voile: #A099A8;        /* texte secondaire, légendes — ≈ 7:1 sur --encre */
  --labiale: #E8A33D;      /* piste 0 · B P M */
  --semi-labiale: #4DC8D4; /* piste 1 · F V   ⚠️ limite en petit corps : surfaces et traits seulement */
  --avancee: #B48CE8;      /* piste 2 · OU O U */
  --ouverture: #7FD48C;    /* piste 3 · A É I — et le bloc de preuve « 0 requête » */
  --ruban: #0F0D13;        /* fond des rubans rythmo, plus sombre que --encre */
  --rouge: #E8756A;        /* cinquième accent — le COÛT : colonne « sans Axeho », erreurs, refus */

  /* ⚠️ TROISIÈME niveau de gris pour le TEXTE, et il manquait. `--regie` est une couleur de FILET :
     posée sur du texte elle donne 1,2:1 sur le fond — pas « discret », invisible. Quatre libellés en
     étaient là, dont le compteur de section et le droit d'auteur du pied. Un jeton de bordure n'est
     jamais un jeton de texte ; l'ordre est --craie → --voile → --murmure, et ça s'arrête là.
     ⚠️ Calibré sur la surface la plus CLAIRE où il se pose, pas sur le fond nu. Les voiles de
     profondeur éclaircissent les pistes et le pied ; réglé sur --encre seul, ce gris repassait sous
     le seuil précisément là où il sert — le droit d'auteur et le compte de modules.
     ⚠️ Deux réglages ont été nécessaires : la bande du pipeline cumule le halo cyan de la section ET
     la lumière rasante des pistes, ce qui en fait la surface la plus claire de la page. Un gris qui
     passe partout ailleurs y échouait encore. Toute nouvelle surface plus claire que celle-là
     demande de revérifier cette valeur — c'est elle qui fixe le plancher. */
  --murmure: #948DA0;

  /* ── Le spectre ────────────────────────────────────────────────────────
     Les cinq accents en un seul dégradé : orange, bleu, blanc, violet, rouge. Il ne sert qu'à des
     FILETS — jamais à un fond de section, jamais derrière du texte, jamais sur un bouton. Un dégradé
     posé à plat sur une surface fabrique de la profondeur là où ce site n'en veut pas ; réduit à deux
     pixels de haut, il devient une signature qui ne coûte rien à la lisibilité.
     ⚠️ Le blanc est au CENTRE, pas à une extrémité : placé au bord, il se confondait avec le texte
     courant qui commence juste après. */
  --spectre: linear-gradient(90deg,
    var(--labiale) 0%, var(--semi-labiale) 26%, var(--craie) 50%,
    var(--avancee) 74%, var(--rouge) 100%);

  color-scheme: dark;      /* ⚠️ pas de thème clair : les captures du produit sont sombres et
                              paraîtraient collées sur un site clair, et l'acheteur passe sa journée
                              dans Cappella, Pro Tools et Resolve. Décision de la spec, §1.2. */
  --r: 4px;                /* rayon unique — 0 sur les rubans rythmo */
  --large: 1200px;         /* contenu */
  --texte: 680px;          /* texte long ≈ 72 signes */
  --m: 'IBM Plex Mono', ui-monospace, monospace;
  --titre: 'Bricolage Grotesque', 'Noto Sans', system-ui, sans-serif;
  --corps: 'Noto Sans', system-ui, -apple-system, sans-serif;

  /* ── Alias de transition ───────────────────────────────────────────────
     L'ancien vocabulaire pointe sur le nouveau. Sans ça, renommer les jetons casserait d'un coup les
     trois cents règles écrites avant la refonte, et le site passerait par un état illisible entre
     deux commits. Les alias disparaîtront quand chaque composant aura été repris. */
  --bg: var(--encre); --s1: var(--pellicule); --s2: var(--pellicule); --bd: var(--regie);
  --tx: var(--craie); --tx2: var(--voile); --tx3: var(--voile);
  --ac: var(--craie); --ac2: var(--craie);
  --gn: var(--ouverture); --rd: var(--rouge); --yw: var(--labiale);
}

* { box-sizing: border-box }
html { scroll-behavior: smooth }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto } * { transition: none !important } }

/* ── La profondeur ───────────────────────────────────────────────────────
   Le site était plat : un aplat d'encre du haut au bas, où toutes les surfaces se valaient. Trois
   halos très faibles, tirés des accents eux-mêmes, lui donnent un relief — orange en haut à gauche,
   bleu à droite, violet plus bas.
   ⚠️ Tous sous 7 % d'opacité, et FIXES en arrière-plan (`background-attachment: fixed`) : un halo
   qui défile avec le contenu se remarque comme un décor, un halo immobile se lit comme une lumière.
   ⚠️ Ce sont des HALOS, pas des teintes de fond. Chacun est mesuré pour ne rien coûter au contraste
   du texte posé dessus — la vérification est refaite après coup sur chaque libellé de la page. */
body {
  margin: 0; color: var(--craie);
  background:
    radial-gradient(70rem 42rem at 8% -8%, color-mix(in srgb, var(--labiale) 7%, transparent), transparent 60%),
    radial-gradient(60rem 40rem at 96% 4%, color-mix(in srgb, var(--semi-labiale) 6%, transparent), transparent 58%),
    radial-gradient(74rem 50rem at 50% 42%, color-mix(in srgb, var(--avancee) 5%, transparent), transparent 62%),
    var(--encre);
  background-attachment: fixed, fixed, fixed, fixed;
  /* 17 px, interlignage 1.65 — échelle de rapport 1.250 de la spec. Noto Sans est choisie pour sa
     couverture de glyphes, pas pour son dessin : c'est elle qui écrit Ɛ ɔ Ɲ Ŋ ẹ ọ ṣ ǹ quand le
     titrage ne les a pas. */
  font: 1.0625rem/1.65 var(--corps);
  -webkit-font-smoothing: antialiased;
}
.inner { width: 100%; max-width: var(--large); margin: 0 auto; padding: 0 24px }

/* Accessibilité : le lien d'évitement ne se voit qu'au clavier, mais il doit alors être bien visible. */
.saut {
  position: absolute; left: 0; top: 0; z-index: 100;
  /* Retire de l'affichage sans sortir de l'arbre d'accessibilite : « left:-9999px »
     deplace le focus hors ecran et fait sauter la page au clavier. */
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
  background: var(--craie); color: var(--encre); padding: 10px 18px; border-radius: 0 0 var(--r) 0; font-weight: 600;
}
.saut:focus { clip-path: none; overflow: visible }

:focus-visible { outline: 2px solid var(--craie); outline-offset: 3px; border-radius: var(--r) }

/* ⚠️ Les liens sont en --craie SOULIGNÉ, jamais en couleur de piste. Une couleur de piste sur un lien
   la viderait de son sens : elle ne désignerait plus une famille phonétique, juste « cliquable ». */
a { color: var(--craie); text-decoration: none }
a:hover { text-decoration: underline }
/* Dans le texte courant, le soulignement est l'état par DÉFAUT : sur fond sombre et sans couleur
   d'accent, c'est la seule chose qui distingue encore un lien d'un mot en gras. */
main p a, main li a, main dd a, main .chapo a { text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: var(--voile) }
main p a:hover, main li a:hover, main dd a:hover { text-decoration-color: var(--craie) }
/* ⚠️ Un BOUTON n'est pas un lien dans une phrase. La règle ci-dessus soulignait « Télécharger
   6.190.0 » et « Voir la bande rythmo » parce qu'ils vivent dans un <p class="cta"> : un bouton
   plein, souligné, se lit comme un défaut de rendu. Les boutons portent déjà leur surface. */
main p a.b, main li a.b, main dd a.b { text-decoration: none }

/* ── En-tête ─────────────────────────────────────────────────────────────
   Cinq objets, dans l'ordre où on s'en sert : la marque, le menu, la recherche, le téléchargement,
   la langue. La spec ramène quinze entrées à cinq ; ce qui disparaît de la barre n'est pas perdu,
   il est rangé dans le méga-menu, qui raconte le déroulé du travail au lieu de le lister. */
.tete { border-bottom: 1px solid var(--regie); background: color-mix(in srgb, var(--encre) 92%, transparent);
        backdrop-filter: blur(10px); position: sticky; top: 0; z-index: 20 }
/* Le spectre en tête de page, sur deux pixels. C'est la seule chose du site qui montre les cinq
   accents ensemble, et elle le fait là où elle ne recouvre aucun texte. Elle voyage avec la barre
   collante : le repère reste à l'écran, comme la ligne de départ d'une rythmo. */
.tete::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 2px; background: var(--spectre) }
/* ⚠️ `>` et non un descendant quelconque : le méga-menu vit DANS cette barre et ses propres
   conteneurs portent aussi la classe `.inner`. En descendant, cette règle leur imposait
   `display:flex` par-dessus la grille à trois colonnes — les colonnes sortaient inégales et
   décalées verticalement, sans que rien dans la feuille du méga-menu ne l'explique. */
.tete > .inner { display: flex; align-items: center; gap: 8px; min-height: 64px; flex-wrap: wrap }
/* Le nom nu, en capitales espacées. Pas de logo à côté du mot : la marque tient dans son dessin de
   lettres, et un pictogramme redoublant le nom ne dit rien de plus. */
/* Le nom en MONOSPACE très espacé, pas en titrage. C'est ce qui le fait lire comme une étiquette de
   matériel — le vocabulaire du métier — plutôt que comme un logotype de start-up. */
.logo { font-family: var(--m); font-weight: 600; font-size: 14px; letter-spacing: .28em;
        text-transform: uppercase; color: var(--craie); margin-right: 12px; white-space: nowrap }
.logo:hover { text-decoration: none }
/* Les entrées ramassées dans une pilule : elles forment un objet, et la barre cesse d'être une
   rangée de mots flottants entre le nom et les boutons. */
.menu { display: flex; align-items: center; gap: 2px; margin: 0 auto;
        background: var(--pellicule); border: 1px solid var(--regie); border-radius: 999px; padding: 5px }
.menu > a { color: var(--craie); font-size: 13px; padding: 8px 16px; border-radius: 999px }
.menu > a:hover { background: var(--encre); text-decoration: none }
.menu > a[aria-current="page"] { background: var(--encre) }

/* La recherche : un LIEN déguisé en champ. Sans script il mène à l'aide, avec script il ouvre la
   palette. Ce n'est pas un `<input>` — un champ qui ne se remplit pas est un mensonge d'interface. */
.rech { display: flex; align-items: center; gap: 10px; margin-left: auto; min-width: 200px;
        background: var(--pellicule); border: 1px solid var(--regie); border-radius: var(--r);
        padding: 7px 8px 7px 12px; color: var(--voile); font-size: 13.5px }
.rech:hover { color: var(--craie); border-color: #4A4453; text-decoration: none }
.rech kbd { font-size: 11px; letter-spacing: .04em; margin-left: auto; color: var(--voile);
            border: 1px solid var(--regie); border-radius: 3px; padding: 2px 6px; background: none }
/* ⚠️ Qualifié par `.tete` : `.b` est déclaré plus bas dans ce fichier, à spécificité égale, et
   gagnait donc. Le bouton sortait à 50 px de haut dans une barre de 64 — il la faisait gonfler. */
.tete .tete-dl { padding: 9px 18px; font-size: 14.5px; white-space: nowrap }
.langue { font-size: 12px; letter-spacing: .06em; color: var(--voile);
          border: 1px solid var(--regie); padding: 6px 10px; border-radius: var(--r) }
.langue:hover { color: var(--craie); border-color: #4A4453; text-decoration: none }

/* ── Méga-menu ───────────────────────────────────────────────────────────
   Bâti sur `<details>` : il s'ouvre au clavier et fonctionne sans une ligne de script. Le panneau
   est en `position: absolute` sous la barre, d'où le `position: static` du `<details>` lui-même. */
/* ⚠️ La maquette ouvre ce panneau au SURVOL. Il reste sur `<details>`, donc au clic : un menu qui
   s'ouvre au passage de la souris est inatteignable au clavier et s'ouvre tout seul au doigt sur
   tablette. Le geste change, la composition non. */
.mega { position: relative }
.mega > summary { cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 7px;
                  color: var(--craie); font-size: 13px; padding: 8px 16px; border-radius: 999px }
.mega > summary::-webkit-details-marker { display: none }
.mega > summary:hover, .mega[open] > summary { background: var(--encre) }
.mega-chevron { font-size: 9px; opacity: .7; transition: transform 120ms ease }
.mega[open] .mega-chevron { transform: rotate(180deg) }
/* Un panneau posé sous son déclencheur, pas une nappe pleine largeur : la barre est désormais
   centrée, et un panneau qui court d'un bord à l'autre ne dit plus de quel bouton il tombe. */
.mega-panneau { position: absolute; top: calc(100% + 10px); left: 50%; transform: translateX(-50%);
                width: min(620px, calc(100vw - 48px)); z-index: 21;
                background: var(--pellicule); border: 1px solid var(--regie); border-radius: var(--r) }
/* `minmax(0, 1fr)` et non `1fr` : « Sous-titres et livraison » ne se laisse pas comprimer, et une
   piste `1fr` nue s'élargit jusqu'à son contenu — les trois colonnes cessaient d'être égales. */
.mega-grille { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
               align-items: start; gap: 20px; padding: 20px; max-width: none }
.mega-col { padding-right: 20px; border-right: 1px solid var(--regie) }
.mega-col:last-child { border-right: 0; padding-right: 0 }
/* Une phase, une couleur — les mêmes quatre que les pistes, et pour la même raison : elles encodent
   les familles phonétiques de la détection. Elles ne touchent ni un bouton ni un lien. */
.mega-phase { display: flex; align-items: baseline; gap: 10px; margin: 0 0 16px;
              font-family: var(--m); font-size: .72rem; letter-spacing: .14em; text-transform: uppercase }
.mega-rang { opacity: .8 }
.mega-phase--labiale { color: var(--labiale) }
.mega-phase--semi-labiale { color: var(--semi-labiale) }
.mega-phase--avancee { color: var(--avancee) }
.mega-phase--ouverture { color: var(--ouverture) }
.mega-liens { display: flex; flex-direction: column; gap: 2px }
.mega-liens a { display: block; padding: 10px 12px; margin-left: -12px; border-radius: var(--r) }
.mega-liens a:hover { background: #241F2B; text-decoration: none }
.mega-liens a { padding: 8px 10px; margin-left: -10px }
.mega-nom { display: block; font-size: 13.5px; font-weight: 600; color: var(--craie) }
.mega-bref { display: block; font-size: 12.5px; color: var(--voile); margin-top: 2px }
.mega-pied { border-top: 1px solid var(--regie) }
.mega-pied .inner { display: flex; align-items: center; gap: 16px; max-width: none;
                    padding: 11px 20px }
.mega-pied a { font-size: 14px; color: var(--voile) }
.mega-pied .fine { margin: 0 0 0 auto; font-size: .72rem; color: var(--murmure) }

@media (max-width: 1020px) {
  /* La recherche part la première : la bulle d'assistance couvre déjà ce besoin sur petit écran,
     et c'est l'objet le plus large de la barre. */
  .rech { display: none }
  .menu { margin-left: auto }
}
@media (max-width: 860px) {
  .tete > .inner { padding-top: 10px; padding-bottom: 10px; gap: 10px }
  .menu { order: 3; width: 100%; margin: 0; justify-content: center; border-radius: var(--r) }
  .tete-dl { margin-left: auto }
  /* ⚠️ Le panneau se cale sur la BARRE, plus sur son déclencheur. Centré sur un bouton qui n'est plus
     au milieu de l'écran, il sortait de 64 px à gauche — invisible, et sans débordement de page pour
     le signaler puisque `overflow-x: clip` le coupait proprement. */
  .mega { position: static }
  .mega-panneau { left: 12px; right: 12px; width: auto; transform: none;
                  max-height: 70vh; overflow-y: auto }
  .mega-grille { grid-template-columns: 1fr; gap: 22px; padding: 20px 16px }
  .mega-col { padding: 0; border-right: 0 }
  .mega-col + .mega-col { border-top: 1px solid var(--regie); padding-top: 20px }
}

/* ── Contenu ─────────────────────────────────────────────────────────── */
main { padding: 44px 24px 72px }
/* Titrage en Bricolage Grotesque : sa largeur variable permet littéralement d'étirer les mots comme
   une bande rythmo, ce qui est le parti pris du site. */
h1, h2, h3 { font-family: var(--titre); text-wrap: balance }
h1 { font-size: clamp(2.6rem, 5vw, 4.2rem); line-height: 1.06; letter-spacing: -.02em; margin: 0 0 18px;
     font-weight: 600 }
h1 em { font-style: normal; color: var(--voile) }
h2 { font-size: clamp(1.9rem, 3vw, 2.6rem); line-height: 1.15; letter-spacing: -.018em; margin: 56px 0 14px;
     font-weight: 600 }
h2:first-child { margin-top: 0 }
h3 { font-size: 1.4rem; line-height: 1.25; font-weight: 500; letter-spacing: -.01em }
p { margin: 0 0 14px; color: var(--voile); max-width: var(--texte) }
strong { color: var(--craie); font-weight: 600 }
.chapo { font-size: 1.25rem; color: var(--voile); max-width: var(--texte); margin-bottom: 28px }
.fine { font-size: .875rem; color: var(--voile) }
/* Les données — timecodes, versions, empreintes, chiffres — sont en Plex Mono. Le chiffre est une
   donnée technique dans ce métier, pas un argument marketing : il doit se lire comme tel. */
.donnee, code, kbd { font-family: var(--m); font-size: .9375rem; letter-spacing: .04em }

/* ── Héros ───────────────────────────────────────────────────────────────
   Deux colonnes : ce qu'on dit à gauche, ce que ça donne à droite. La capture n'est plus reléguée au
   milieu de la page — c'est un logiciel qu'on vend, et son interface est sa seule photographie. */
.hero { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; padding: 56px 0 }
.hero-dire .chapo { max-width: 46ch; margin: 0 0 24px; font-size: 1.1875rem; color: var(--craie) }
.hero-dire .cta { margin: 0 0 18px }
.hero-dire .fine { margin: 0; font-size: .75rem; letter-spacing: .04em }

/* Les éclats d'interface posés autour de la capture. Ils sont EXTRAITS de l'application — une
   réplique et son timecode, un débit, un rôle — et non inventés : c'est ce qui fait lire l'outil au
   lieu de le regarder. À plat, sans ombre : ce sont le filet et le fond qui les détachent. */
.hero-vue { position: relative }
.hero-vue .capture { margin: 0 }
.hero-vue .capture figcaption { display: none }
/* ⚠️ RECADRÉE, et c'est un choix, pas un accident. rythmo.png fait 3840 × 823 — un rapport de 4,67:1.
   Posée en largeur dans cette colonne elle tombe à 118 px de haut : la bande y est un filet, le texte
   des répliques illisible, et les trois éclats posés autour font le double de sa hauteur. Recadrée en
   `cover`, on voit les quarante premiers pour cent à deux fois et demie l'échelle — la bande devient
   lisible. La capture entière reste disponible plus bas, dans la visionneuse. */
.hero-vue .capture img { height: clamp(220px, 24vw, 320px); object-fit: cover; object-position: left center }
.eclat { position: absolute; margin: 0; max-width: none; z-index: 2;
         background: var(--pellicule); border: 1px solid var(--regie); border-radius: var(--r);
         padding: 9px 13px; font-size: .7rem; color: var(--craie); line-height: 1.5 }
.eclat span { display: block; color: var(--voile) }
.eclat--replique { top: -16px; right: -20px }
.eclat--debit { bottom: 34%; left: -24px; font-size: .85rem }
.eclat--role { bottom: -14px; right: 40px; color: var(--voile) }

/* L'éclat de réplique est un <details> : la seule des trois qui donne quelque chose à ouvrir. Un
   clic dessus montre la même détection labiale que la page Détection, appliquée à cette réplique —
   la méthode du produit, pas une image de plus. */
.eclat--replique { padding: 0; cursor: default; transition: max-width 120ms }
.eclat--replique summary { list-style: none; padding: 9px 13px; cursor: pointer;
                            display: flex; align-items: center; gap: 8px }
.eclat--replique summary::-webkit-details-marker { display: none }
.eclat--replique summary::after { content: '+'; color: var(--voile); font-size: .85rem; flex: none }
.eclat--replique[open] summary::after { content: '−' }
.eclat--replique[open] { z-index: 5; max-width: min(300px, calc(100vw - 48px)) }
.eclat-detail { padding: 0 13px 12px }
/* Le bandeau phonétique existe déjà, en pleine largeur, sur la page Détection : ici il tient dans
   un éclat de 300 px, donc plus petit — jamais un second dispositif, la même mécanique réduite. */
.eclat-detail .phonetique { background: none; border: 0; border-radius: 0; padding: 0; margin: 8px 0 0;
                             border-top: 1px solid var(--regie); padding-top: 10px }
.eclat-detail .phonetique-mot { font-size: .95rem; margin: 0 0 8px; max-width: none }
.eclat-detail .phonetique-legende { font-size: .6875rem; gap: 3px 10px }
@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; gap: 32px; padding: 40px 0 }
  /* Sur une colonne étroite, un éclat qui déborde de vingt pixels sort de l'écran. Ils rentrent. */
  .eclat--replique { top: -12px; right: 0 }
  .eclat--debit { left: 0; bottom: 12px }
  .eclat--role { display: none }
}

.cta { display: flex; gap: 12px; flex-wrap: wrap; margin: 24px 0 12px }

.b { display: inline-flex; align-items: center; justify-content: center; gap: 8px; touch-action: manipulation;
     padding: 12px 20px; border: 1px solid transparent; border-radius: 999px;
     font-size: 14px; font-weight: 600; cursor: pointer; font-family: inherit; text-align: center;
     white-space: nowrap }
.b:hover { text-decoration: none }
.ba { background: var(--craie); color: var(--encre) }
.ba:hover { background: #fff }
.ba:disabled { opacity: .5; cursor: default }
/* État d'attente : le bouton reste actionnable et annoncé, il dit seulement qu'il travaille. */
.b[aria-busy="true"] { opacity: .72; cursor: progress }
.bg { background: var(--s2); color: var(--tx); border-color: var(--bd) }
.bg:hover { border-color: var(--tx3) }

/* Rayon 4 px partout, comme le reste du site depuis la refonte : un coin arrondi à 14 px sur fond
   sombre ramollit la grille, et c'est la rigueur d'alignement qui porte cette direction. */
.card { background: var(--pellicule); border: 1px solid var(--regie); border-radius: var(--r); padding: 22px }
.card h3 { margin: 0 0 10px; font-size: 17px; line-height: 1.3; font-weight: 700; letter-spacing: -.01em }
.card p:last-child { margin-bottom: 0 }

.grid3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); gap: 24px; margin: 0 }

.bande { border-top: 1px solid var(--bd); margin-top: 48px; padding-top: 32px }
.fin { border-top: 1px solid var(--bd); margin-top: 48px; padding-top: 32px; max-width: 68ch }

ul.coches, ol.etapes { padding-left: 0; list-style: none; margin: 0 0 18px; max-width: 76ch }
ul.coches li { position: relative; padding-left: 26px; margin-bottom: 9px; color: var(--tx2) }
ul.coches li::before { content: '✓'; position: absolute; left: 0; top: 0; color: var(--gn); font-weight: 700 }
ol.etapes { counter-reset: e }
ol.etapes li { counter-increment: e; position: relative; padding-left: 32px; margin-bottom: 11px; color: var(--tx2) }
ol.etapes li::before {
  content: counter(e); position: absolute; left: 0; top: 1px; width: 22px; height: 22px;
  border-radius: 50%; background: var(--s2); border: 1px solid var(--bd);
  font-size: 12px; font-weight: 700; color: var(--tx2); display: grid; place-items: center;
}

.note { background: var(--s1); border: 1px solid var(--bd); border-left: 3px solid var(--yw);
        border-radius: 0 var(--r) var(--r) 0; padding: 14px 18px; font-size: 14.5px; max-width: 76ch }
.note code { font-family: var(--m); font-size: 13px }

/* ── Questions des pages de service et de l'aide ─────────────────────────
   Le même traitement en cartes que l'accordéon de l'accueil, pour que les questions se ressemblent
   d'une page à l'autre.
   ⚠️ Elles restent en `<dl>/<dt>/<dd>` OUVERTES, et pas en `<details>` repliés comme l'accueil.
   Deux raisons. Sur les pages de service, chaque question porte une ANCRE permanente qu'on colle
   dans un ticket d'assistance : arriver sur une réponse fermée annulerait tout l'intérêt du lien.
   Et partout, la recherche du navigateur (Ctrl+F) ne trouve pas le texte d'un `<details>` fermé —
   or c'est exactement le repli qu'on annonce au visiteur quand l'index ne se charge pas. */
/* ⚠️ PAS de `display:flex; gap`. Le gap s'insère entre TOUS les enfants — donc aussi entre un `dt` et
   son propre `dd` — et coupait chaque carte en deux moitiés flottantes. L'espacement se met sur le
   `dt`, qui ouvre la carte suivante ; le `dd` reste collé à sa question. */
dl.faq { max-width: 76ch; margin: 0 0 18px }
dl.faq dt { font-family: var(--titre); font-weight: 500; font-size: 1.05rem; color: var(--craie);
            background: var(--pellicule); border: 1px solid var(--regie);
            border-radius: var(--r) var(--r) 0 0; border-bottom: 0;
            padding: 16px 20px 10px; margin: 10px 0 0 }
dl.faq dt:first-child { margin-top: 0 }
dl.faq dd { margin: 0; color: var(--voile); font-size: .95rem; line-height: 1.65;
            background: var(--pellicule); border: 1px solid var(--regie);
            border-radius: 0 0 var(--r) var(--r); border-top: 0; padding: 0 20px 16px }

/* ── Téléchargement ──────────────────────────────────────────────────── */
.dl { display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
      background: var(--s1); border: 1px solid var(--bd); border-radius: 14px; padding: 22px; margin: 26px 0 }
.dl-main { flex: 1; min-width: 200px }
.dl-main h2 { margin: 0 0 4px; font-size: 18px }
.grid3 .card h3 { color: var(--tx) }

/* ── Tarifs ──────────────────────────────────────────────────────────── */
/* `#offres` porte maintenant le bandeau de durées ET les grilles : la grille descend d'un cran. */
/* ── L'aurore derrière les tarifs ───────────────────────────────────────────
   Deux masses floutées qui dérivent lentement, pour donner de la profondeur à la zone des prix.
   Purement décoratif : `aria-hidden` côté balisage, `pointer-events: none` ici.

   Les teintes sont celles des QUATRE PISTES de la bande rythmo — labiale, semi-labiale, avancée,
   ouverture. C'est la signature visuelle de la maison, et l'employer ici fait de la page des tarifs
   une page d'Axeho plutôt qu'un gabarit interchangeable. Elles ne servent qu'à colorer un flou de
   110 px : aucune n'est lisible comme un signal, aucune ne peut se confondre avec la bande.

   ⚠️ Le flou de 110 px sur des masses de 600 px coûte cher à composer. On les confine dans un
   conteneur qui ne se repeint pas (`contain`), et on les arrête net pour qui a demandé moins
   d'animations — une page de tarifs ne doit pas donner la nausée à qui la consulte. */
.offres { position: relative; margin: 28px 0; isolation: isolate }
.aurore {
  position: absolute; inset: -180px -160px; z-index: -1;
  pointer-events: none; overflow: visible;
}
.aurore span {
  position: absolute; display: block; aspect-ratio: 1;
  filter: blur(70px); mix-blend-mode: screen; will-change: transform;
}
/* Chaque masse est un dégradé radial qui s'éteint AVANT son propre bord : il n'y a donc aucune
   frontière à voir, et rien à découper. C'est ce que « se confondre dans le fond » demande. */
.aurore .a1 { width: min(66vw, 720px); top: -14%; left: -10%;
  background: radial-gradient(circle closest-side, color-mix(in srgb, var(--avancee) 42%, transparent), transparent 72%) }
.aurore .a2 { width: min(58vw, 620px); bottom: -18%; right: -8%;
  background: radial-gradient(circle closest-side, color-mix(in srgb, var(--semi-labiale) 30%, transparent), transparent 72%) }
.aurore .a3 { width: min(50vw, 520px); top: 26%; right: 22%;
  background: radial-gradient(circle closest-side, color-mix(in srgb, var(--labiale) 22%, transparent), transparent 70%) }
@media (prefers-reduced-motion: no-preference) {
  .aurore .a1 { animation: aurore1 26s ease-in-out infinite alternate }
  .aurore .a2 { animation: aurore2 32s ease-in-out infinite alternate }
  .aurore .a3 { animation: aurore3 38s ease-in-out infinite alternate }
}
@keyframes aurore1 { to { transform: translate(90px, 60px) scale(1.12) } }
@keyframes aurore2 { to { transform: translate(-80px, -50px) scale(1.08) } }
@keyframes aurore3 { to { transform: translate(-60px, 70px) scale(1.15) } }

.offres-grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); gap: 16px; margin: 18px 0 }
.offres .attente { color: var(--tx3); font-size: 14.5px }

/* ── Choix de la durée ──────────────────────────────────────────────────────
   Placé AVANT les cartes : c'est lui qui commande les prix affichés dessous. Sous les cartes, on
   lirait des montants qui changent sous les yeux sans savoir pourquoi. */
/* Le commutateur commande TOUS les prix de la page. Discret, il passait inaperçu et on croyait
   qu'une seule durée existait. Il est donc annoncé par un intitulé et dimensionné pour se voir. */
.durees-barre { display: flex; align-items: center; justify-content: center; gap: 14px;
                flex-wrap: wrap; margin: 8px 0 4px }
.durees-titre { font-size: 14px; font-weight: 600; color: var(--tx2) }
.durees { display: inline-flex; gap: 3px; padding: 4px; background: var(--s2); border: 1px solid var(--bd); border-radius: 12px }
.duree-b {
  padding: 11px 22px; font: inherit; font-size: 15px; font-weight: 650; color: var(--tx3);
  background: none; border: 0; border-radius: 9px; cursor: pointer; transition: color .12s, background .12s;
}
.duree-b:hover { color: var(--tx) }
.duree-b:focus-visible { outline: 2px solid var(--ac); outline-offset: 2px }
.duree-b.actif { color: var(--encre); background: var(--ac); box-shadow: 0 1px 3px rgba(0,0,0,.25) }

/* Seconde grille de prix — les forfaits pour indépendants. Elle SUIT la première, sans repli :
   ce qui se vend se montre. */
.offres-section { margin-top: 48px; border-top: 1px solid var(--bd); padding-top: 34px }
.offres-section > h2 { margin: 0 0 6px; font-size: 24px; font-weight: 700; letter-spacing: -.02em }
.offres-section > .fine { margin: 0; font-size: 15px; color: var(--tx3); max-width: 64ch }
.offre .prix .par { font-size: 14px; font-weight: 500; color: var(--tx3); letter-spacing: 0 }
.offre .eco { font-size: 12.5px; font-weight: 600; color: var(--ac); margin: 4px 0 0 }
.offre.gratuite { border-style: dashed }
.offre.gratuite .etiq { color: var(--tx3) }

/* Perpétuelles et forfaits par métier : sous un pli. Quatre cartes se lisent, seize non — et ces
   deux familles ne concernent qu'une minorité de visiteurs, qui sauront les ouvrir. */
/* ── Le pli des forfaits par métier ─────────────────────────────────────────
   Il portait un simple intitulé, aligné à gauche, avec un petit triangle. Résultat : personne ne le
   voyait, et on en concluait que ces forfaits n'avaient pas de prix. Un repli qui contient des
   TARIFS n'est pas une note de bas de page — il doit s'annoncer comme une porte.
   D'où un vrai bouton, centré, à la taille d'un appel à l'action. */
.pli-offres { margin-top: 40px; border-top: 1px solid var(--bd); padding-top: 32px; text-align: center }
.pli-offres > summary {
  display: inline-flex; align-items: center; gap: 12px;
  margin: 0 auto; padding: 16px 30px; cursor: pointer;
  font-size: 18px; font-weight: 650; letter-spacing: -.015em; color: var(--tx);
  background: var(--s1); border: 1px solid var(--ac); border-radius: 12px;
  transition: background .15s, transform .15s;
}
.pli-offres > summary:hover { background: var(--s2); transform: translateY(-1px) }
.pli-offres > summary:focus-visible { outline: 2px solid var(--ac); outline-offset: 3px }
/* Le triangle par défaut est minuscule et mal placé dans un bouton : on le remplace par un chevron
   dessiné, qui pivote à l'ouverture et dit donc ce que le clic va faire. */
.pli-offres > summary::marker, .pli-offres > summary::-webkit-details-marker { content: ''; display: none }
.pli-offres > summary::after {
  content: ''; width: 9px; height: 9px; border-right: 2px solid var(--ac); border-bottom: 2px solid var(--ac);
  transform: rotate(45deg) translate(-2px, -2px); transition: transform .2s;
}
.pli-offres[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px) }
.pli-offres .fourchette { color: var(--ac); font-weight: 600 }
/* Le contenu, lui, retrouve l'alignement du reste de la page. */
.pli-contenu { text-align: left; margin-top: 24px }
.pli-offres .fine { margin: 0 auto 8px; font-size: 14px; color: var(--tx3); max-width: 62ch; text-align: center }
/* ── Les cartes ─────────────────────────────────────────────────────────────
   Fond translucide sur l'aurore, et un halo qui s'allume au survol. Le halo est posé en
   `::before` DERRIÈRE le contenu : peint sur la carte elle-même, il passerait par-dessus le texte
   ou obligerait à empiler des `z-index` sur chaque enfant. */
.offre {
  position: relative; isolation: isolate;
  background: color-mix(in srgb, var(--s1) 82%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid var(--bd); border-radius: 18px; padding: 24px;
  display: flex; flex-direction: column;
  transition: transform .25s ease, border-color .25s ease, box-shadow .25s ease;
}
.offre::before {
  content: ''; position: absolute; inset: -1px; z-index: -1; border-radius: inherit;
  background: radial-gradient(120% 100% at 20% 0%, var(--avancee), transparent 62%),
              radial-gradient(120% 100% at 90% 100%, var(--semi-labiale), transparent 60%);
  opacity: 0; transition: opacity .35s ease;
}
.offre:hover::before, .offre:focus-within::before { opacity: .5 }
.offre.vedette::before { background: radial-gradient(120% 100% at 20% 0%, var(--labiale), transparent 60%),
                                     radial-gradient(120% 100% at 90% 100%, var(--avancee), transparent 62%); opacity: .28 }
@media (prefers-reduced-motion: no-preference) {
  .offre:hover, .offre:focus-within { transform: translateY(-6px) }
}
.offre:hover, .offre:focus-within { border-color: color-mix(in srgb, var(--ac) 45%, var(--bd)) }

/* Entrée en cascade, au PREMIER affichage seulement : rejouée à chaque changement de durée, elle
   ferait clignoter toute la page à chaque clic. `--i` est posé sur la carte par le script. */
@media (prefers-reduced-motion: no-preference) {
  .offres-grille[data-entree] > .offre { animation: monte .55s cubic-bezier(.22,.61,.36,1) both;
                                         animation-delay: calc(var(--i, 0) * 70ms) }
}
@keyframes monte { from { opacity: 0; transform: translateY(18px) } to { opacity: 1; transform: none } }

.offre.vedette { border-color: var(--ac); box-shadow: 0 0 0 1px var(--ac) }
/* L'étiquette « le plus choisi » devient un vrai bandeau, coin supérieur droit. */
.offre.vedette .etiq {
  position: absolute; top: 0; right: 0; margin: 0; padding: 6px 14px;
  color: var(--encre); background: var(--ac); border-radius: 0 18px 0 14px; min-height: 0;
}
.offre .etiq { font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
               color: var(--ac); margin-bottom: 8px; min-height: 15px }
.offre h3 { margin: 0 0 6px; font-size: 21px; font-weight: 700; letter-spacing: -.015em }
.offre .resume { font-size: 14.5px; color: var(--tx3); margin-bottom: 18px }
.offre .prix { font-size: 30px; font-variant-numeric: tabular-nums; font-weight: 700; letter-spacing: -.03em; color: var(--tx); line-height: 1.1 }
.offre .duree { font-size: 13px; color: var(--tx3); margin: 5px 0 18px }
.offre ul { flex: 1; margin-bottom: 20px }
.offre .couvre { margin: 14px 0 8px; font-size: 11px; font-weight: 600; letter-spacing: .08em;
                 text-transform: uppercase; color: var(--tx3) }
/* ⚠️ DEUX RÉGLAGES, ET LE SECOND EST CELUI QUI COMPTE. `.offre ul { flex: 1 }` visait la liste des
   avantages, mais il attrapait AUSSI celle des services : la liste s'étirait sur toute la hauteur
   restante de la carte, et comme `.puces` est une boîte flexible qui étire ses enfants par défaut,
   chaque pastille devenait un disque de deux cents pixels avec le texte collé en haut. Régler le
   remplissage seul n'aurait rien changé — une boîte étirée ne se règle pas au padding. */
.offre .puces.petites { flex: 0 0 auto; align-items: flex-start; margin: 0 0 18px; gap: 6px }
.puces.petites li { font-size: 12.5px; padding: 2px; border-radius: 999px; line-height: 1.5;
                    background: color-mix(in srgb, var(--s2) 70%, transparent) }
.puces.petites a { color: var(--tx2) }
.puces.petites a:hover { color: var(--ac) }
.offre .b { width: 100% }

.achat { max-width: 480px; margin: 8px 0 34px }
.achat h2 { margin-top: 0 }
.fld { margin-bottom: 16px }
label { display: block; font-size: 13.5px; color: var(--tx2); margin-bottom: 6px; font-weight: 500 }
input, select {
  width: 100%; background: var(--s2); border: 1px solid var(--bd); border-radius: var(--r);
  color: var(--tx); padding: 12px 13px; font-size: 15.5px; font-family: inherit;
}
input:invalid:not(:placeholder-shown) { border-color: var(--rd) }
.achat .fine { margin: 6px 0 0 }
.achat .b { margin-right: 8px }
.msg { font-size: 14px; margin: 14px 0 0; min-height: 20px }
.msg.err { color: var(--rd) }
.msg.okc { color: var(--gn) }

.ferme { background: var(--s1); border: 1px solid var(--bd); border-left: 3px solid var(--ac);
         border-radius: 0 var(--r) var(--r) 0; padding: 15px 18px; font-size: 14.5px; margin: 0 0 24px }

/* ── Captures de l'application ────────────────────────────────────────
   Le produit est un logiciel : c'est son interface qui l'illustre. Les images portent leurs
   dimensions réelles dans le HTML — sans elles la page saute au chargement, et c'est le
   défaut de mise en page le plus visible pour un visiteur comme pour un moteur. */
.capture { margin: 32px 0 36px; padding: 0 }
.capture img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--bd); border-radius: 12px;
  background: #09090b;   /* pendant le chargement, le cadre a déjà la couleur de l'application */
}
.capture figcaption { margin-top: 11px; font-size: 13px; color: var(--tx3); max-width: 76ch }

/* ── Tutoriels ───────────────────────────────────────────────────────── */
/* Une étape numérotée, son texte, puis SA capture. L'ordre compte : l'image vient après la consigne,
   parce qu'on lit ce qu'il faut faire avant de chercher où le faire. */
.sommaire { background: var(--s1); border: 1px solid var(--bd); border-radius: 12px;
            padding: 18px 22px; margin: 28px 0 40px; max-width: 68ch }
.sommaire ol { margin: 0; padding-left: 20px }
.sommaire li { margin: 5px 0 }

/* Le même tutoriel, en un fichier. ⚠️ Discret, et pas un bouton : la page EST la version de référence,
   le PDF sert à qui travaille loin d'elle — sur un second écran, en cabine, ou sur papier. Lui donner
   l'allure d'un appel à l'action ferait croire qu'il faut télécharger pour lire. */
/* ── Par métier ───────────────────────────────────────────────────────────
   Six portes, posées avant le rangement par service. Des pastilles et non une liste : on les lit
   d'un balayage, et on n'en choisit qu'une. */
.metiers { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 30px }
.metiers a, .metier-ici {
  font-size: 14px; padding: 7px 15px; border-radius: 20px; border: 1px solid var(--bd);
  background: var(--s1); text-decoration: none; color: var(--tx2);
}
.metiers a:hover { border-color: var(--ac); color: var(--tx) }
/* Celui où l'on se trouve déjà : marqué, et surtout PAS cliquable — un lien vers la page qu'on lit
   est un faux départ, et c'est la première chose qu'on essaie sur une rangée pareille. */
.metier-ici { border-color: var(--ac); color: var(--tx); cursor: default }

.pdf-rangee { display: flex; flex-wrap: wrap; gap: 10px 22px; margin: 0 0 8px }
.pdf-lien { font-size: 13.5px; color: var(--tx2); text-decoration: none;
            border-bottom: 1px solid var(--bd); padding-bottom: 2px }
.pdf-lien:hover { color: var(--tx); border-bottom-color: var(--tx) }
.pdf-lien span { font-family: var(--m); opacity: .7 }

.tuto { border-top: 1px solid var(--bd); margin-top: 52px; padding-top: 30px }
.tuto > .fine { margin-top: -6px }

/* ⚠️ Les étapes réutilisent `.flux`, qui existait déjà pour le déroulé du travail : numéro en pastille,
   filet qui relie, dernier maillon ouvert. En écrire un second jeu produisait deux styles d'étapes sur
   le même site — et le mien PERDAIT de toute façon, `ol.etapes li::before` étant plus spécifique que
   `.etapes > li::before`. Deux variantes du même objet, dont une invisible : le pire des deux mondes.
   Il ne reste donc ici que ce qui manquait vraiment à `.flux` : l'encadré de mise en garde et l'image. */
.flux .note { margin: 12px 0 0 }

/* ⚠️ `width: 100%` NE convient PAS ici : ces captures sont recadrées sur quelques boutons et ne font
   parfois que 400 px de large. Les étirer sur toute la colonne les rendrait floues. On plafonne à leur
   taille réelle, et on ne réduit que si la colonne est plus étroite. */
.etape-img {
  display: block; max-width: 100%; height: auto; margin: 16px 0 0;
  border: 1px solid var(--bd); border-radius: 10px; background: #09090b;
}

/* ⚠️ Une capture de rangée d'outils fait 1400 px de large. Tenue dans la colonne d'une étape (1090 px
   au mieux), elle descend à 0,7 : les libellés que l'étape vient de nommer tombent en corps 8, et le
   lecteur ne les reconnaît plus. Ces captures-là SORTENT de la colonne, vers la droite.

   Trois plafonds, et le plus petit gagne :
   ① `--capture-l`, la taille réelle du fichier — on ne l'agrandit JAMAIS, une capture étirée est floue ;
   ② la place restante à droite jusqu'à la gouttière, l'image partant du bord gauche du contenu ;
   ③ la fenêtre entière moins ses gouttières, pour les écrans plus étroits que le contenu.
   ⚠️ Sans ② une capture déborde la fenêtre sur les écrans de 1440 px et fait apparaître une barre de
   défilement horizontale sur toute la page — le défaut se voit à 1440 et pas à 1920, donc jamais
   pendant qu'on l'écrit. Sans ③, même chose en dessous de 1250 px. */
.etape-img--large {
  max-width: none;
  width: min(var(--capture-l), calc(50vw + (var(--large) - 48px) / 2 - 24px), calc(100vw - 48px));
  /* Ramène le bord gauche de la capture sur celui du contenu : la colonne d'une étape est en retrait
     du rail numéroté. ⚠️ 61px = les deux valeurs de `.flux > li` ci-dessus (marge 15 + retrait 46). */
  margin-left: -61px;
}
/* Sur un écran étroit, le rail et la colonne ne font plus qu'un : le débordement n'a plus d'objet, et
   la marge négative ferait sortir la capture de l'écran par la gauche. */
@media (max-width: 860px) {
  .etape-img--large { width: 100%; margin-left: 0 }
}

/* ── Tableaux ────────────────────────────────────────────────────────── */
/* Le tableau déborde dans SON propre conteneur : sur mobile c'est lui qui défile,
   jamais la page entière. */
.tw { overflow-x: auto; margin: 0 0 22px; border: 1px solid var(--bd); border-radius: 12px }
table { border-collapse: collapse; width: 100%; font-size: 14.5px; min-width: 460px }
th, td { text-align: left; padding: 11px 15px; border-bottom: 1px solid var(--bd); vertical-align: top }
th { font-size: 12.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--tx3);
     font-weight: 700; background: var(--s1); white-space: nowrap }
tbody tr:last-child td { border-bottom: none }
td { color: var(--tx2) }
td strong, td code { color: var(--tx) }
td code { font-size: 13px }

/* ── Bandeau de chiffres ─────────────────────────────────────────────── */
.chiffres { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px;
            margin: 34px 0; padding: 26px 0; border-top: 1px solid var(--bd); border-bottom: 1px solid var(--bd) }
.chiffres div { text-align: center }
.chiffres b { display: block; font-size: 30px; font-weight: 700; letter-spacing: -.03em; color: var(--ac); line-height: 1.1 }
.chiffres span { display: block; font-size: 13.5px; color: var(--tx3); margin-top: 5px }

/* ── Étapes du flux de travail ───────────────────────────────────────── */
.flux { counter-reset: f; margin: 26px 0 32px; padding: 0; list-style: none }
.flux > li { counter-increment: f; position: relative; padding: 0 0 26px 46px; border-left: 1px solid var(--bd);
             margin-left: 15px }
.flux > li:last-child { border-left-color: transparent; padding-bottom: 0 }
.flux > li::before {
  content: counter(f); position: absolute; left: -16px; top: -2px; width: 31px; height: 31px;
  border-radius: 50%; background: var(--bg); border: 1px solid var(--ac); color: var(--ac);
  font-size: 13px; font-weight: 700; display: grid; place-items: center;
}
.flux h3 { margin: 0 0 6px; font-size: 16.5px; font-weight: 700; color: var(--tx) }
.flux p { margin: 0; color: var(--tx2); max-width: 70ch }

/* ── Étiquettes (listes de langues, de formats) ──────────────────────── */
.puces { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 22px; padding: 0; list-style: none }
.puces li { font-size: 13.5px; color: var(--tx2); background: var(--s1); border: 1px solid var(--bd);
            border-radius: 20px; padding: 5px 13px }
.puces li.fort { border-color: var(--ac); color: var(--ac) }

/* ── Pied ─────────────────────────────────────────────────────────────────
   Deux rangs : la marque et les liens, puis le droit d'auteur et la preuve. La preuve est répétée
   sur CHAQUE page parce que c'est là qu'elle sert : un visiteur qui ouvre l'onglet Réseau le fait sur
   la page où il se trouve, pas sur l'accueil. */
.pied { border-top: 1px solid var(--regie); margin-top: 96px }
.pied-haut { display: flex; gap: 40px; flex-wrap: wrap; align-items: flex-start;
             padding-top: 40px; padding-bottom: 44px }
.pied .marque { font-family: var(--titre); font-weight: 700; font-size: 17px; letter-spacing: .05em;
                text-transform: uppercase; color: var(--craie); margin: 0 0 6px }
.pied-marque .fine { margin: 0; color: var(--murmure) }
.pied .liens { display: flex; gap: 48px; flex-wrap: wrap; margin-left: auto }
.pied-col { display: flex; flex-direction: column; gap: 8px }
.pied-titre { margin: 0 0 4px; font-size: 13px; font-weight: 600; color: var(--craie) }
.pied .liens a { font-size: 13px; color: var(--voile) }
.pied-bas { border-top: 1px solid var(--regie) }
.pied-bas .inner { display: flex; gap: 20px; flex-wrap: wrap; align-items: center;
                   padding-top: 15px; padding-bottom: 15px }
.pied-bas p { margin: 0; font-size: .72rem; color: var(--murmure) }
.preuve-pastille { margin-left: auto !important; display: flex; align-items: center; gap: 8px;
                   color: var(--ouverture) !important }
.pastille { width: 6px; height: 6px; border-radius: 50%; background: var(--ouverture);
            animation: pulse-preuve 2.4s ease-in-out infinite }
@keyframes pulse-preuve { 0%, 100% { opacity: .35 } 50% { opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .pastille { animation: none; opacity: 1 } }

code { font-family: var(--m); font-size: .9em; background: var(--s2); padding: 2px 6px; border-radius: 5px }

/* ── Palette ⌘K ──────────────────────────────────────────────────────────
   Le public est clavier-centré : cent quatre-vingt-dix-neuf réponses indexées méritent mieux qu'une
   bulle qu'il faut aller chercher à la souris. La bulle reste, comme affordance mobile. */
.pal-fond { position: fixed; inset: 0; z-index: 80; padding: 12vh 20px 20px;
            background: rgba(10, 8, 12, .72); backdrop-filter: blur(3px) }
.pal { max-width: 620px; margin: 0 auto; background: var(--pellicule);
       border: 1px solid var(--regie); border-radius: var(--r); overflow: hidden }
.pal-champ { width: 100%; background: none; border: 0; border-bottom: 1px solid var(--regie);
             border-radius: 0; color: var(--craie); padding: 18px 20px; font-size: 1rem }
.pal-champ:focus { outline: none }
.pal-champ::placeholder { color: var(--murmure) }
.pal-liste { max-height: 46vh; overflow-y: auto }
.pal-liste a { display: block; padding: 13px 20px; border-bottom: 1px solid var(--regie) }
.pal-liste a:hover, .pal-liste a:focus-visible { background: #241F2B; text-decoration: none }
.pal-q { display: block; font-size: .95rem; color: var(--craie) }
.pal-src { display: block; font-size: .72rem; color: var(--murmure); margin-top: 3px }
/* L'état sans réponse est un moment de direction, pas une excuse : il oriente vers le vocabulaire
   du métier au lieu de s'excuser. */
.pal-vide { margin: 0; padding: 22px 20px; font-size: .95rem; color: var(--craie); max-width: none }
.pal-vide span { display: block; margin-top: 6px; font-size: .875rem; color: var(--voile) }
.pal-pied { margin: 0; padding: 11px 20px; font-size: .72rem; color: var(--murmure);
            border-top: 1px solid var(--regie) }

/* ── Assistant ───────────────────────────────────────────────────────── */
.ax-bulle {
  position: fixed; right: 20px; bottom: 20px; z-index: 40;
  width: 54px; height: 54px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--craie); color: var(--encre); display: grid; place-items: center;
}
.ax-bulle:hover { background: #fff }
.ax-bulle.ax-actif { transform: rotate(90deg) }

.ax-panneau {
  position: fixed; right: 20px; bottom: 86px; z-index: 41;
  width: min(390px, calc(100vw - 40px)); max-height: min(560px, calc(100vh - 120px));
  display: flex; flex-direction: column;
  background: var(--s1); border: 1px solid var(--bd); border-radius: 16px;
  overflow: hidden;
}
.ax-panneau[hidden] { display: none }
.ax-tete { display: flex; align-items: center; justify-content: space-between; gap: 10px;
           padding: 14px 16px; border-bottom: 1px solid var(--bd) }
.ax-tete strong { font-size: 15px }
.ax-fermer { background: none; border: none; color: var(--tx3); cursor: pointer; font-size: 16px;
             line-height: 1; padding: 4px 6px; border-radius: 6px }
.ax-fermer:hover { color: var(--tx); background: var(--s2) }

.ax-fil { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 10px }
.ax-msg { font-size: 14.5px; line-height: 1.55; padding: 10px 13px; border-radius: 12px;
          max-width: 88%; white-space: pre-wrap; overflow-wrap: anywhere }
.ax-assistant { background: var(--s2); border: 1px solid var(--bd); color: var(--tx2); align-self: flex-start }
.ax-user { background: var(--ac); color: #fff; align-self: flex-end }
.ax-attente { color: var(--tx3); font-style: italic }
.ax-panne { border-color: var(--rd); color: var(--rd) }

/* ── Passage à un humain ────────────────────────────────────────────────────
   Le formulaire s'ouvre DANS le fil, à la suite de la conversation : ouvrir une fenêtre par-dessus
   ferait perdre la question qu'on vient de poser, et c'est elle qu'on veut voir partir. */
.ax-ok { border-color: var(--vt, #16a34a) }
.ax-aide { color: var(--tx3); font-size: .86rem; margin: 0 0 .5rem }
.ax-form-h { display: flex; flex-direction: column; gap: .45rem }
.ax-form-h input, .ax-form-h textarea {
  width: 100%; padding: .45rem .6rem; font: inherit; font-size: .9rem;
  color: var(--tx); background: var(--s2); border: 1px solid var(--bd); border-radius: 10px;
}
.ax-form-h textarea { resize: vertical; min-height: 4.5rem }
.ax-humain-lien {
  align-self: flex-start; margin-top: .2rem; padding: .3rem .55rem;
  font: inherit; font-size: .82rem; color: var(--ac); cursor: pointer;
  background: none; border: 1px dashed var(--bd); border-radius: 6px;
}
.ax-humain-lien:hover { border-style: solid }

.ax-q { display: block; font-size: 14px; color: var(--tx); margin-bottom: 5px }
.ax-r { margin: 0; color: var(--tx2) }
.ax-src { margin: 9px 0 0; font-size: 12.5px; color: var(--tx3) }
.ax-autres { margin: 12px 0 7px; font-size: 12.5px; color: var(--tx3) }
.ax-msg .ax-sugg { margin-top: 0 }

.ax-sugg { display: flex; flex-direction: column; gap: 7px; align-items: flex-start }
.ax-sugg button { font: inherit; font-size: 13.5px; text-align: left; cursor: pointer;
                  background: transparent; color: var(--ac); border: 1px solid var(--bd);
                  border-radius: 18px; padding: 7px 13px }
.ax-sugg button:hover { border-color: var(--ac) }

.ax-form { display: flex; gap: 8px; padding: 12px 14px; border-top: 1px solid var(--bd) }
.ax-champ { flex: 1; font-size: 14.5px; padding: 10px 12px }
.ax-envoi { background: var(--ac); color: #fff; border: none; border-radius: var(--r);
            padding: 10px 15px; font: inherit; font-size: 14px; font-weight: 600; cursor: pointer }
.ax-envoi:disabled { opacity: .5; cursor: default }
.ax-avert { margin: 0; padding: 0 14px 13px; font-size: 11.5px; color: var(--tx3) }

@media (max-width: 480px) {
  .ax-panneau { right: 12px; left: 12px; width: auto; bottom: 80px }
  .ax-bulle { right: 14px; bottom: 14px }
}

/* ══ REFONTE ═══════════════════════════════════════════════════════════════
   Le dispositif rythmo, et rien d'autre. Il n'apparaît qu'à trois endroits — le héros de l'accueil,
   les séparateurs de section, le schéma du pipeline. On dépense l'audace à un seul endroit. */

/* ── Le ruban ────────────────────────────────────────────────────────────
   ⚠️ `overflow-x: clip` et non `hidden` : `hidden` fabrique un conteneur de défilement, ce qui tue le
   `position: sticky` de l'en-tête. `clip` coupe sans créer ce conteneur. */
html { overflow-x: clip }

/* ⚠️ PAS de marge négative en tête. Elle remontait le ruban de 44 px pour le coller au bord haut —
   c'est-à-dire SOUS l'en-tête collante, qui en mange 65. Le repère de piste, posé en haut du ruban,
   se retrouvait entièrement caché derrière la barre : la ligne qui dit « timecode, piste 0, 25 i/s »,
   celle qui fait reconnaître l'outil au premier coup d'œil, était invisible. */
.hero-rythmo { margin-inline: calc(50% - 50vw); margin-bottom: 0 }
.ruban {
  position: relative;
  background: var(--ruban); border-block: 1px solid var(--regie);
  border-radius: 0;                 /* ⚠️ 0 sur les rubans, contrairement au reste du site */
  padding: 26px 0;
}
/* Le repère de piste : aligné sur la colonne de texte, FIXE, hors du bloc qui défile. */
.ruban-tc { max-width: var(--large); margin: 0 auto 14px; padding: 0 24px;
            font-size: .75rem; letter-spacing: .1em; color: var(--voile) }
/* ⚠️ Le fondu des deux bords passe par `mask-image` et non plus par un dégradé posé en `::before` :
   le dégradé devait connaître la couleur du fond, donc il se voyait dès qu'un ruban était posé sur
   une autre surface. Le masque, lui, découpe — il marche sur n'importe quel fond. */
.ruban-piste { position: relative; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent) }
/* Deux exemplaires identiques glissent de -50 % : c'est ce qui donne une boucle sans coupure.
   `width: max-content` est indispensable — sans lui le ruban hérite de la largeur du parent et le
   texte se replie au lieu de défiler. C'est le défaut qui faisait se chevaucher les lettres. */
.ruban-defile { display: flex; width: max-content; animation: rythmo 42s linear infinite }
.ruban:hover .ruban-defile, .ruban:focus-within .ruban-defile { animation-play-state: paused }
.ruban-texte {
  flex: 0 0 auto; white-space: nowrap; padding-right: 120px;
  margin: 0; max-width: none;
  font-family: var(--titre); font-weight: 700; letter-spacing: -.02em;
  /* ⚠️ `font-stretch` demande l'axe `wdth`. La Bricolage embarquée ne porte que `opsz` et `wght` :
     la propriété serait ignorée SANS AUCUN message, et le geste « texte étiré comme sur une rythmo »
     disparaîtrait sans qu'on s'en aperçoive. Elle n'est donc pas écrite ici tant que la fonte n'a pas
     été refaite avec cet axe — vérifiable en relisant fvar dans le .woff2. */
  font-size: clamp(2.6rem, 6vw, 5rem); line-height: 1.02; color: var(--craie);
}
/* Les deux seules couleurs de piste autorisées ici : elles nomment des familles phonétiques. */
.ruban-texte .lab { color: var(--labiale); font-weight: inherit }
.ruban-texte .sl  { color: var(--semi-labiale); font-weight: inherit }

/* La ligne de départ, fixe, que le texte franchit. C'est elle qui fait lire « bande rythmo »
   plutôt que « bandeau défilant ».
   ⚠️ Un vrai élément plutôt qu'un `::after`, parce que `::before` porte déjà le dégradé d'entrée et
   de sortie : deux pseudo-éléments, c'est le maximum, et le troisième geste du ruban n'avait plus de
   place. Positionné avec un z-index, il se peint au-dessus du texte quel que soit l'ordre du source. */
.ruban-repere {
  position: absolute; left: 34%; top: 0; bottom: 0; width: 1px; z-index: 2;
  background: var(--craie); opacity: .45;
}
/* Le texte doit ENTRER et SORTIR, pas surgir. */
.ruban::before {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: linear-gradient(90deg, var(--encre) 0, transparent 14%, transparent 86%, var(--encre) 100%);
}
@keyframes rythmo { from { transform: translateX(0) } to { transform: translateX(-50%) } }
/* ⚠️ Figé sur une IMAGE, jamais sur du vide : à translateX(0) la ligne de départ tomberait avant le
   premier mot et le ruban paraîtrait cassé. */
@media (prefers-reduced-motion: reduce) {
  .ruban-defile { animation: none; transform: translateX(-25%) }
}

/* ── Pastille de version ─────────────────────────────────────────────────
   Le numéro et la date sortent des mêmes repères que partout ailleurs, et version.js les remplace
   à l'exécution. Dire « 6.190.0, publiée le 10 août » prouve qu'un logiciel est vivant ; l'écrire
   en dur prouve surtout qu'on a oublié de le mettre à jour, ce qui est exactement ce qui est arrivé. */
.pastille-version { display: block; width: fit-content; margin: 0 auto 24px;
                    font-size: .72rem; color: var(--voile);
                    border: 1px solid var(--regie); border-radius: var(--r); padding: 6px 14px }

/* ── Barre de preuve ─────────────────────────────────────────────────────
   Quatre colonnes séparées par un filet, centrées, sans cadre autour : le bandeau encadré se lisait
   comme un encart publicitaire. Nu, il se lit comme un relevé. */
.chiffres { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            margin: 0 0 72px; text-align: center }
.chiffres > div { padding: 0 12px; border-right: 1px solid var(--regie) }
.chiffres > div:last-child { border-right: 0 }
.chiffres b { display: block; font-family: var(--m); font-size: clamp(1.6rem, 3vw, 2rem);
              font-weight: 400; letter-spacing: .02em; color: var(--craie); margin-bottom: 6px }
.chiffres span { font-size: .75rem; color: var(--voile); line-height: 1.45 }

/* ── Le pipeline en quatre pistes ────────────────────────────────────────
   ⚠️ Des LIGNES empilées, pas des cartes côte à côte. Quatre cartes se lisent comme quatre options
   entre lesquelles choisir ; quatre lignes, chacune ouverte par son numéro de piste et son filet de
   couleur, se lisent comme une suite — ce qu'est le travail. La forme dit la chose. */
.pipeline { display: flex; flex-direction: column; gap: 2px; margin: 0 }
.piste { position: relative; display: grid;
         grid-template-columns: 56px minmax(0, 190px) minmax(0, 1fr) auto;
         align-items: center; gap: 24px; padding: 20px 24px 20px 27px;
         background: var(--encre); border: 1px solid var(--regie);
         border-radius: 0 var(--r) var(--r) 0 }
/* Le filet de piste s'éteint vers le bas — la couleur marque le DÉBUT de la phase, comme un repère
   d'entrée, au lieu de border la ligne sur toute sa hauteur. */
.piste::before { content: ""; position: absolute; left: 0; top: -1px; bottom: -1px; width: 3px }
.piste:hover { background: var(--pellicule); text-decoration: none }
.piste-n { font-size: .75rem; letter-spacing: .1em }
.piste-nom { font-family: var(--titre); font-size: 1.4rem; font-weight: 600; color: var(--craie);
             text-transform: uppercase; letter-spacing: .01em }
.piste-resume { font-size: .9375rem; color: var(--voile) }
/* Les modules de la phase, nommés mais non cliquables : un lien dans un lien est invalide, et le
   méga-menu donne déjà l'accès module par module. Ici ils servent à dire ce que la phase contient. */
.piste-mods { display: block; color: var(--murmure); font-size: .8125rem; margin-top: 3px }
.piste-compte { font-size: .78rem; color: var(--murmure); white-space: nowrap }
/* Une phase = une piste = une famille phonétique. Le filet est le SEUL porteur de la couleur. */
.piste--labiale::before { background: linear-gradient(180deg, var(--labiale), transparent) }
.piste--labiale .piste-n { color: var(--labiale) }
.piste--semi-labiale::before { background: linear-gradient(180deg, var(--semi-labiale), transparent) }
.piste--semi-labiale .piste-n { color: var(--semi-labiale) }
.piste--avancee::before { background: linear-gradient(180deg, var(--avancee), transparent) }
.piste--avancee .piste-n { color: var(--avancee) }
.piste--ouverture::before { background: linear-gradient(180deg, var(--ouverture), transparent) }
.piste--ouverture .piste-n { color: var(--ouverture) }
@media (max-width: 860px) {
  .piste { grid-template-columns: 56px minmax(0, 1fr); gap: 6px 20px; align-items: start; padding: 18px 20px }
  .piste-n { grid-row: 1 }
  .piste-nom { grid-column: 2 }
  .piste-resume { grid-column: 2 }
  .piste-compte { grid-column: 2; margin-top: 4px }
}

/* Le pipeline occupe toute la largeur, sur un fond plus sombre : c'est le seul moment de la page où
   le regard sort de la colonne de texte, et c'est ce qui distingue un schéma d'une illustration. */
.bande-pipeline { margin: 96px calc(50% - 50vw) 0; padding: 56px calc(50vw - 50%) 64px;
                  background: var(--ruban); border-top: 1px solid var(--regie);
                  border-bottom: 1px solid var(--regie) }
.bande-pipeline .titre-section { border-bottom: 0; padding-bottom: 0; margin-bottom: 30px }
/* ⚠️ `background-color` et non le raccourci `background` : le raccourci remet `background-image` à
   `none`, et cette règle — plus spécifique que le voile de profondeur écrit plus bas — effaçait la
   lumière rasante des quatre pistes sans rien signaler. Elles restaient plates au milieu d'une page
   qui, elle, avait pris du relief. */
.bande-pipeline .piste { background-color: var(--pellicule) }
.bande-pipeline .piste:hover { background-color: #241F2B }

/* ── Bloc de souveraineté ────────────────────────────────────────────────
   La seule autre place de --ouverture. Une promesse vérifiable vaut dix promesses affirmées.
   ⚠️ Le compte des zéros est SÉPARÉ du texte, sur son propre panneau : noyé dans un paragraphe, il
   se lisait comme une figure de style. Isolé et en Plex Mono, il se lit comme un relevé. */
/* ⚠️ `.preuve` reste un ENCADRÉ générique — la page Gestion s'en sert pour « Le problème », avec un
   simple h2 et un paragraphe. Le bloc de souveraineté de l'accueil, lui, est une composition à deux
   panneaux : il a pris son propre nom. Tant qu'ils partageaient `.preuve`, la grille à deux colonnes
   coupait l'encadré de Gestion en deux moitiés et lui collait la bordure verte du « 0 requête », qui
   ne veut rien dire là-bas. Un nom générique pour un composant spécifique finit toujours ainsi. */
.preuve { border: 1px solid var(--regie); border-left: 3px solid var(--regie);
          border-radius: 0 var(--r) var(--r) 0; background: var(--pellicule);
          padding: 24px 28px; margin: 32px 0 }
.preuve h2 { margin-top: 0 }
.preuve p:last-child { margin-bottom: 0 }

.souverainete { display: grid; grid-template-columns: 1.2fr 1fr; margin: 0;
          border: 1px solid var(--ouverture); border-radius: var(--r); overflow: hidden }
.souverainete-dire { padding: 32px }
.souverainete-dire p { max-width: 60ch; color: var(--craie); font-size: .97rem }
.souverainete-dire p:last-child { margin-bottom: 0 }
.souverainete-compte { padding: 32px; background: var(--ruban); border-left: 1px solid var(--regie);
                 display: flex; flex-direction: column; justify-content: center; gap: 16px }
/* Le chiffre à gauche, son libellé poussé à droite : la colonne de zéros s'aligne, et c'est cet
   alignement qui la fait lire comme un relevé plutôt que comme trois phrases. */
.souverainete-compte p { display: flex; align-items: center; justify-content: space-between; gap: 14px;
                   margin: 0; max-width: none }
/* ⚠️ Les zéros sont en --craie, PAS en vert. Seule la bordure du bloc porte --ouverture : trois
   grands chiffres colorés attirent l'œil sur la couleur au lieu du fait, et la règle des couleurs
   de piste veut qu'elles restent des repères, jamais des ornements. */
.souverainete-compte b { font-size: 2.4rem; font-weight: 400; line-height: 1; color: var(--craie) }
.souverainete-compte span { font-size: .75rem; color: var(--voile); text-align: right }
.souverainete-compte .fine { display: block; font-size: .7rem; color: var(--voile);
                       border-top: 1px solid var(--regie); padding-top: 12px; margin: 0 }
@media (max-width: 860px) {
  .souverainete { grid-template-columns: 1fr }
  .souverainete-dire { padding: 24px }
  .souverainete-compte { padding: 24px; border-left: 0; border-top: 1px solid var(--regie) }
}

/* ── Grille des langues ──────────────────────────────────────────────────
   ⚠️ Les africaines sont mises en relief par le CONTRASTE — fond plein, bordure claire — et jamais
   par une couleur de piste : celles-ci désignent des familles phonétiques et n'ont rien à dire sur
   une langue. */
.langues { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 40px; margin: 0 }
.langues .eyebrow { border-left: 0; padding-left: 0; font-family: var(--m); font-weight: 400;
                    letter-spacing: .14em; margin-bottom: 16px; color: var(--voile) }
.langues-liste { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 0; padding: 0;
                 align-content: flex-start }
/* Pastilles pleinement arrondies — la seule exception au rayon de 4 px du site, parce qu'un nom de
   langue n'est pas une surface d'interface : c'est une étiquette, et une étiquette est ovale. */
.langues-liste li { font-size: .8125rem; border-radius: 999px; padding: 7px 14px;
                    border: 1px solid var(--regie); color: var(--voile) }
/* ⚠️ Les africaines en INVERSE — encre sur craie. C'est le plus fort contraste dont dispose la page,
   et il est dépensé là volontairement : c'est le seul endroit du site qui rend visible ce qu'aucun
   concurrent n'affiche. Toujours pas de couleur de piste : celles-ci nomment des familles
   phonétiques et n'ont rien à dire sur une langue. */
.langues-afr + .langues-liste li { background: var(--craie); color: var(--encre); border-color: var(--craie) }
.langues-col .fine { margin: 20px 0 0; max-width: 44ch }
/* Le contrôle de glyphes : pas une démonstration, une vérification, et elle se fait chez le lecteur.
   Si l'une de ces lettres tombe en fonte de substitution, il le voit à l'œil nu. */
.glyphes { margin: 20px 0 0; font-size: .72rem; line-height: 1.9; color: var(--voile) }
.glyphes-chaine { display: block; font-size: 1.35rem; letter-spacing: .06em; color: var(--craie) }

/* ── Les modules, avec leur geste ────────────────────────────────────────
   Trois puis deux. Chaque brique porte SON visuel — dessiné en balisage, jamais une image : le site
   ne charge rien d'un autre domaine, et cinq vignettes n'ont pas à coûter cinq requêtes.
   ⚠️ Sept pages sur un gabarit unique finissent par se ressembler ; c'est le visuel de tête qui les
   empêche de paraître clonées. Même raison ici, en petit. */
.modules { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin: 0 0 36px }
.module { display: block; background: var(--pellicule); border: 1px solid var(--regie);
          border-radius: var(--r); padding: 20px }
.module:hover { background: #241F2B; text-decoration: none }
.module-vue { display: flex; align-items: flex-end; height: 44px; margin-bottom: 16px; overflow: hidden }
.module-nom { display: block; font-weight: 600; font-size: .9375rem; color: var(--craie); margin-bottom: 6px }
.module-bref { display: block; font-size: .8125rem; line-height: 1.5; color: var(--voile) }
@media (max-width: 900px) { .modules { grid-template-columns: repeat(2, 1fr) } }
@media (max-width: 560px) { .modules { grid-template-columns: 1fr } }

/* Les cinq vignettes. Chacune montre le geste du module, pas une icône interchangeable. */
.v-onde { display: flex; align-items: flex-end; gap: 2px; height: 100% }
.v-onde i { width: 4px; background: var(--voile) }
.v-onde .v-gap { width: 14px; background: none }
.v-onde .v-a { background: var(--labiale) }
.v-onde .v-b { background: var(--avancee) }
.v-mot { display: flex; align-items: center; height: 100%; font-size: 1.35rem; letter-spacing: .02em }
.v-mot i { font-style: normal }
.v-bande { display: block; position: relative; width: 100%; height: 100%;
           border-bottom: 1px solid var(--regie) }
.v-depart { position: absolute; left: 34%; top: 0; bottom: 0; width: 1px; background: var(--craie) }
.v-timelines { display: flex; flex-direction: column; justify-content: center; gap: 6px;
               width: 100%; height: 100% }
.v-timelines i { display: block; height: 6px; width: 70%; background: var(--voile) }
.v-timelines .v-decale { margin-left: 18%; background: var(--ouverture) }
.v-releve { display: flex; flex-direction: column; justify-content: center; gap: 4px;
            height: 100%; font-size: .68rem; color: var(--voile) }
.v-releve i { font-style: normal }

/* ── Intertitre de section ───────────────────────────────────────────────
   Le titre, sa note, et son rang dans la page. Le rang répond à la seule question que se pose un
   lecteur sur une page longue — « où j'en suis ? » — sans barre de progression et sans script. */
/* ⚠️ Le filet du titre passe par un `::after` et non par `border-bottom` : une bordure ne prend pas
   de dégradé sans `border-image`, qui casse le rayon et se comporte mal au retour à la ligne. Le
   dégradé part de la couleur et s'éteint — il souligne le début du titre, pas toute la largeur. */
.titre-section { position: relative; display: flex; align-items: baseline; gap: 20px; flex-wrap: wrap;
                 padding-bottom: 14px; margin: 96px 0 36px }
.titre-section::after { content: ""; position: absolute; inset: auto 0 0 0; height: 1px;
                        background: linear-gradient(90deg, var(--craie), var(--regie) 22%, var(--regie)) }
.titre-section h2 { margin: 0 }
.titre-note { margin: 0; font-size: .9375rem; color: var(--voile); max-width: 52ch }
.titre-n { margin-left: auto; font-size: .72rem; letter-spacing: .12em; color: var(--murmure) }
/* La première section suit le bandeau de chiffres, qui pose déjà sa propre respiration. */
main > .titre-section:first-of-type { margin-top: 0 }

/* ── Carte « problème » ──────────────────────────────────────────────────
   Trois temps, dans cet ordre : ce qu'on entend dire, pourquoi ça coûte, ce qu'Axeho y fait. Le
   troisième est en --craie, les deux premiers en --voile : la réponse doit se détacher du constat,
   sinon la carte se lit comme une plainte. Le lien reste collé au bas, quelle que soit la longueur. */
/* Deux temps, pas trois : ce qu'on entend dire, puis ce qu'Axeho y fait. Le constat en --voile, la
   réponse en --craie et en gras. Sans ce contraste, la carte se lit comme une plainte. */
.card--probleme { display: flex; flex-direction: column; padding: 24px; border-radius: var(--r) }
.card--probleme p { font-size: .9375rem; line-height: 1.6; max-width: none }
.card--probleme .dit { color: var(--voile); margin: 0 0 16px }
.card--probleme .reponse { color: var(--craie); font-weight: 600; margin: 0 0 12px }
/* Le renvoi est en monospace et non souligné : c'est une étiquette de destination, pas une phrase
   cliquable au milieu d'un texte. */
.card--probleme .vers { margin: auto 0 0; font-family: var(--m); font-size: .7rem; letter-spacing: .04em }
.card--probleme .vers a { color: var(--voile); text-decoration: none }
.card--probleme .vers a:hover { color: var(--craie); text-decoration: underline }

/* ── Comparatif ──────────────────────────────────────────────────────────
   Deux colonnes en vis-à-vis, ligne à ligne. Le site disait ce qu'Axeho fait ; il ne disait jamais
   ce que ça remplace, ni ce que l'autre chemin coûte. C'est la section qui répond à ça.
   ⚠️ Aucun concurrent n'est nommé. On oppose des situations de production, pas des marques. */
.duel { display: grid; grid-template-columns: 1fr 1fr; margin: 0;
        border: 1px solid var(--regie); border-radius: var(--r); overflow: hidden }
.duel-col { padding: 22px 24px }
.duel-col .eyebrow { border-left: 0; padding-left: 0; margin-bottom: 18px;
                     font-family: var(--m); font-weight: 400; letter-spacing: .05em; color: var(--voile) }
.duel-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px }
.duel-col li { font-size: .9rem; line-height: 1.5; padding-left: 26px; position: relative }
.duel-col li::before { position: absolute; left: 0; top: 0; font-family: var(--m) }
/* ⚠️ Le rouge n'entre QUE dans cette colonne, et c'est le seul endroit du site où il a un sens :
   c'est celle qui chiffre ce que coûte l'autre chemin. Employé ailleurs — sur un bouton, sur un
   titre — il annoncerait un danger là où il n'y en a pas, et il perdrait ici tout son tranchant. */
.duel-col { position: relative }
.duel-col::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px }
.duel-col--avec::before { background: linear-gradient(180deg, var(--ouverture), transparent) }
.duel-col--avec li { color: var(--craie) }
.duel-col--avec li::before { content: "✓"; color: var(--ouverture) }
.duel-col--sans::before { background: linear-gradient(180deg, var(--rouge), transparent) }
.duel-col--sans li { color: var(--voile) }
.duel-col--sans li::before { content: "✗"; color: var(--rouge) }
@media (max-width: 760px) {
  .duel { grid-template-columns: 1fr }
  .duel-col--sans { border-top: 1px solid var(--regie) }
}

/* ── Questions en accordéon ──────────────────────────────────────────────
   ⚠️ Le numéro est posé par un COMPTEUR CSS, pas écrit dans le balisage. Écrit, il entrerait dans
   l'index de l'assistant et chaque question y arriverait sous la forme « 01 Faut-il une connexion » ;
   et il faudrait renuméroter à la main dès qu'on intercale une question. */
.faq-acc { max-width: 820px; margin: 0; counter-reset: q;
           display: flex; flex-direction: column; gap: 10px }
/* Chaque question est une CARTE, plus une ligne dans une liste. Empilées sans surface, les six
   questions se lisaient comme un paragraphe découpé ; posées chacune sur la sienne, on voit qu'il y
   a six objets, et qu'ils s'ouvrent. */
.faq-acc details { counter-increment: q; background: var(--pellicule);
                   border: 1px solid var(--regie); border-radius: var(--r) }
.faq-acc details[open] { background: #241F2B }
/* ⚠️ Une GRILLE, pas un flex. En flex, `margin-left:auto` ne pousse à droite que le dernier enfant —
   l'étiquette de thème restait collée à la question, au milieu de la ligne. En grille, la colonne du
   texte prend `1fr` et repousse d'elle-même l'étiquette et le « + » vers le bord, y compris quand
   l'étiquette est absente : le texte de la question est un nœud NU, impossible à cibler en CSS, et
   c'est la grille qui en fait un élément à part entière sans toucher au balisage. */
.faq-acc summary { cursor: pointer; list-style: none;
                   display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto;
                   align-items: baseline; gap: 16px; padding: 18px 20px;
                   font-family: var(--titre); font-weight: 500; font-size: 1.1rem; color: var(--craie) }
.faq-acc summary::-webkit-details-marker { display: none }
.faq-acc summary::before { content: counter(q, decimal-leading-zero); font-family: var(--m);
                           font-weight: 400; font-size: .72rem; color: var(--voile); flex: none }
/* ⚠️ La seule affordance qui manquait vraiment : RIEN ne disait que ces questions s'ouvraient. Un
   « + » qui bascule en « × » le dit sans un mot, et la rotation est portée par la même transition de
   120 ms que le reste du site — ce n'est pas une seconde animation, c'est un état interactif. */
.faq-acc summary::after { content: "+";
                          font-family: var(--m); font-size: 1.25rem; line-height: 1; color: var(--voile);
                          transition: transform 120ms ease, color 120ms ease }
.faq-acc details[open] summary::after { transform: rotate(45deg); color: var(--craie) }
.faq-acc summary:hover { color: #fff }
.faq-acc summary:hover::after { color: var(--craie) }
/* L'étiquette de thème : elle sert à SCANNER. Sur six questions on cherche la sienne, on ne les lit
   pas toutes — et un mot à droite se repère avant qu'on ait lu la phrase. */
.q-meta { justify-self: end; font-family: var(--m); font-size: .62rem; letter-spacing: .14em;
          text-transform: uppercase; color: var(--voile);
          border: 1px solid var(--regie); border-radius: 999px; padding: 4px 10px }
.faq-acc p { margin: 0 20px 20px 56px; max-width: 680px; font-size: .95rem; line-height: 1.65 }
@media (max-width: 560px) {
  .q-meta { display: none }      /* à 375 px la question tient à peine : l'étiquette la couperait */
  .faq-acc p { margin-left: 20px }
}
.apres-faq { margin-top: 26px }

/* ── Appel final en deux temps ───────────────────────────────────────────
   À gauche l'action qui marche aujourd'hui — télécharger. À droite celle qui n'existe pas encore —
   acheter — dite comme telle. Une page qui promet un achat impossible fabrique de la friction sans
   récompense ; une liste d'attente transforme la même impasse en la seule conversion disponible. */
.fin--duo { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; max-width: none;
            margin: 0; padding: 0; border-top: 0 }
.fin--duo > .card { padding: 28px; border-radius: var(--r); display: flex; flex-direction: column }
.fin--duo h3 { margin: 0 0 10px; font-family: var(--titre); font-weight: 600; font-size: 1.4rem;
               color: var(--craie) }
.fin--duo p { max-width: 52ch }
.fin--duo .cta { margin-top: auto; padding-top: 12px }

/* ── Second produit ──────────────────────────────────────────────────────
   Sur sa propre surface, après le studio, hors du pipeline. Il ne s'adresse pas au même lecteur :
   l'adaptateur veut sa bande, le dirigeant veut le coût de l'épisode. Les mêler dans le parcours
   brouillerait les deux promesses — c'est pourquoi il n'est pas non plus dans le méga-menu. */
.autre-produit { display: grid; grid-template-columns: 1.3fr 1fr; gap: 48px; align-items: center;
                 background: var(--pellicule); border: 1px solid var(--regie); border-radius: var(--r);
                 padding: 40px; margin: 0 }
.autre-produit p { max-width: 56ch }
.autre-produit .card { background: var(--encre); padding: 24px }
.autre-produit .cta { margin: 0 0 14px }
.autre-produit .fine { margin: 0; font-size: .7rem }
@media (max-width: 860px) {
  .fin--duo { grid-template-columns: 1fr }
  .autre-produit { grid-template-columns: 1fr; gap: 28px; padding: 28px }
}
.carte-attente { padding: 32px; border-radius: var(--r) }
.carte-attente h3 { margin: 0 0 10px; font-family: var(--titre); font-weight: 600; font-size: 1.4rem;
                    color: var(--craie) }
.carte-attente .eyebrow { margin-bottom: 8px; border-left: 0; padding-left: 0; font-family: var(--m);
                          font-weight: 400; letter-spacing: .14em; color: var(--labiale) }
.carte-attente .b { width: 100% }
.carte-attente .fine { margin-bottom: 0 }
@media (max-width: 860px) { .fin--duo { grid-template-columns: 1fr; gap: 40px } }

/* Une donnée technique — timecode, version, empreinte, compte — se compose en Plex Mono. Dans ce
   métier un chiffre est un relevé, pas un argument : il doit se lire comme tel. */
.mono { font-family: var(--m) }

/* ── Visionneuse de captures ─────────────────────────────────────────────
   Radios + `:checked`, aucun JavaScript : la page reste entière si un script ne se charge pas. */
.visio { margin: 0 }
/* ⚠️ On DIT ce qui manque plutôt que de laisser trois onglets là où le pipeline en promet quatre :
   un emplacement nommé se lit comme un chantier, un trou se lit comme un oubli. */
.emplacement { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; max-width: none;
               margin: 20px 0 0; padding: 20px 22px; font-size: .9rem;
               border: 1px dashed #3A3346; border-radius: var(--r);
               background: repeating-linear-gradient(135deg, #17141C, #17141C 8px, #1B1721 8px, #1B1721 16px) }
.emplacement .mono { font-size: .72rem; letter-spacing: .1em; color: var(--murmure) }
/* ⚠️ `width: 0` explicite : la règle générique `input { width: 100% }` s'applique aussi à ces radios
   masquées, qui débordaient donc la page de leur largeur pleine — invisibles, mais bien présentes
   dans la boîte de mise en page. */
.visio > input { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; padding: 0; border: 0 }
.visio-onglets { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px }
.visio-onglets label { border: 1px solid var(--regie); padding: 8px 15px; font-size: .9375rem;
                       cursor: pointer; border-radius: var(--r); color: var(--voile) }
.visio-onglets label:hover { border-color: var(--craie); color: var(--craie) }
.visio-vue { display: none; margin: 0 }
.visio-vue img { display: block; width: 100%; height: auto; border: 1px solid var(--regie);
                 border-radius: var(--r); background: var(--ruban) }
.visio-vue figcaption { margin-top: 11px; font-size: .875rem; color: var(--voile); max-width: 76ch }
/* Un onglet coché éclaire son étiquette et découvre sa vue. */
#visio-rythmo:checked ~ .visio-onglets label[for="visio-rythmo"],
#visio-script:checked ~ .visio-onglets label[for="visio-script"],
#visio-transcription:checked ~ .visio-onglets label[for="visio-transcription"] {
  color: var(--encre); background: var(--craie); border-color: var(--craie);
}
#visio-rythmo:checked ~ .visio-vues .visio-vue[data-v="rythmo"],
#visio-script:checked ~ .visio-vues .visio-vue[data-v="script"],
#visio-transcription:checked ~ .visio-vues .visio-vue[data-v="transcription"] { display: block }
/* Le focus clavier doit se voir sur l'étiquette, puisque la radio elle-même est invisible. */
.visio > input:focus-visible ~ .visio-onglets label { outline: 2px solid var(--craie); outline-offset: 3px }

/* ── Gabarit de service ──────────────────────────────────────────────────── */

/* Fil d'Ariane. Le chevron est posé en CSS : il sépare, il ne se lit pas. */
.ariane { display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
          font-size: .875rem; color: var(--voile); margin-bottom: 18px }
.ariane a { color: var(--voile); text-decoration: none }
.ariane a:hover { color: var(--craie); text-decoration: underline }
.ariane > * + *::before { content: "›"; padding-right: 6px; color: var(--murmure) }
.ariane [aria-current] { color: var(--craie) }

/* La phase du pipeline. C'est le SEUL endroit d'une page de service où une couleur de piste
   apparaît : elle dit à quel moment du travail on se trouve, et rien d'autre. */
.eyebrow { display: inline-flex; align-items: center; gap: 10px; margin: 0 0 14px;
           font-family: var(--corps); font-size: .8125rem; font-weight: 700;
           text-transform: uppercase; letter-spacing: .1em; color: var(--voile);
           border-left: 3px solid var(--regie); padding-left: 12px }
.eyebrow-n { font-family: var(--m); font-weight: 400; letter-spacing: .04em; color: var(--murmure) }
.eyebrow--labiale { border-left-color: var(--labiale) }
.eyebrow--semi-labiale { border-left-color: var(--semi-labiale) }
.eyebrow--avancee { border-left-color: var(--avancee) }
.eyebrow--ouverture { border-left-color: var(--ouverture) }

/* Le bandeau phonétique : la méthode du produit montrée sur elle-même. */
.phonetique { background: var(--ruban); border: 1px solid var(--regie); border-radius: var(--r);
              padding: 28px 26px; margin: 26px 0 40px }
.phonetique-mot { font-family: var(--titre); font-weight: 600; letter-spacing: -.02em;
                  font-size: clamp(1.8rem, 4vw, 3rem); line-height: 1.2; color: var(--craie);
                  margin: 0 0 20px; max-width: none }
.phonetique-mot b { font-weight: inherit }
.phonetique-legende { display: flex; flex-wrap: wrap; gap: 8px 22px; list-style: none; margin: 0; padding: 0;
                      font-size: .875rem; color: var(--voile) }
.phonetique-legende .lettres { font-family: var(--m); letter-spacing: .06em; padding-right: 4px }
.lab { color: var(--labiale) }
.sl  { color: var(--semi-labiale) }
.av  { color: var(--avancee) }
.ouv { color: var(--ouverture) }
.phonetique-legende .lab .lettres, .phonetique-legende .sl .lettres,
.phonetique-legende .av .lettres, .phonetique-legende .ouv .lettres { color: inherit }
.phonetique-legende li { color: var(--voile) }
.phonetique-legende li .lettres { font-weight: 600 }
.phonetique-legende li.lab .lettres { color: var(--labiale) }
.phonetique-legende li.sl .lettres { color: var(--semi-labiale) }
.phonetique-legende li.av .lettres { color: var(--avancee) }
.phonetique-legende li.ouv .lettres { color: var(--ouverture) }

/* Tableau de spécifications. Dense, aligné, lisible en diagonale : c'est ce que le professionnel
   scanne avant de lire une seule phrase. Il défile dans SON conteneur, pas dans la page. */
.table-defile { overflow-x: auto; margin: 20px 0 40px; border: 1px solid var(--regie); border-radius: var(--r) }
.specs { width: 100%; border-collapse: collapse; font-size: .9375rem }
.specs th, .specs td { text-align: left; vertical-align: top; padding: 13px 18px;
                       border-bottom: 1px solid var(--regie) }
.specs tr:last-child th, .specs tr:last-child td { border-bottom: 0 }
.specs th { font-family: var(--corps); font-weight: 600; color: var(--craie); white-space: nowrap;
            width: 1%; border-right: 1px solid var(--regie); background: var(--pellicule) }
.specs td { color: var(--voile) }

/* L'ancre permanente d'une question : discrète, mais toujours atteignable au clavier. */
.faq dt { position: relative }
.ancre { color: var(--murmure); text-decoration: none; font-weight: 400; padding-left: 4px }
.faq dt:hover .ancre, .ancre:focus-visible { color: var(--voile) }
/* L'en-tête est collante : sans ce décalage, une ancre place la question SOUS l'en-tête.
   ⚠️ La valeur suit la HAUTEUR RÉELLE de la barre, qui passe de 64 à 114 px quand le menu se replie
   sur une seconde ligne. Figée à 84 px, l'ancre tombait vingt pixels trop haut sur mobile — c'est-
   à-dire pile sur la question qu'on venait de partager en assistance. */
[id] { scroll-margin-top: calc(var(--tete-h) + 20px) }
:root { --tete-h: 64px }
@media (max-width: 860px) { :root { --tete-h: 124px } }

/* Voisins dans le déroulé du travail. Deux liens, jamais « précédent/suivant » en abstrait :
   on nomme le service, sinon le lien n'apprend rien avant d'être cliqué. */
.voisins { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1px;
           background: var(--regie); border: 1px solid var(--regie); margin: 48px 0 0 }
.voisin { display: flex; flex-direction: column; gap: 5px; padding: 18px 20px;
          background: var(--encre); text-decoration: none }
.voisin:hover { background: var(--pellicule); text-decoration: none }
.voisin--apres { text-align: right }
.voisin-sens { font-size: .75rem; text-transform: uppercase; letter-spacing: .1em; color: var(--voile) }
.voisin-nom { font-family: var(--titre); font-size: 1.15rem; font-weight: 600; color: var(--craie) }

/* ══ PROFONDEUR DES SURFACES ═══════════════════════════════════════════════
   Les panneaux étaient des aplats : une carte, un encadré et une piste avaient exactement la même
   valeur, et la page se lisait comme une seule feuille. Une lumière rasante venue du haut les
   sépare — c'est le même principe que les filets, en plus doux.

   ⚠️ Un dégradé de BLANC à 3 %, pas une teinte : une couleur de fond, même faible, déplace toutes
   les couleurs de texte posées dessus et casse les contrastes vérifiés. Un voile neutre les laisse
   intacts, ce qui a été remesuré libellé par libellé après coup.
   ⚠️ Toujours aucune ombre portée. La profondeur vient de la lumière et des filets, pas d'un flou
   sous les objets — c'est ce qui distingue cette page d'une maquette de série. */
.card,
.module,
.faq-acc details,
dl.faq dt, dl.faq dd,
.preuve,
.duel-col,
.piste {
  background-image: linear-gradient(180deg, rgba(255, 255, 255, .035), rgba(255, 255, 255, 0) 62%);
}
/* Au survol la lumière monte d'un cran : l'objet se soulève sans bouger. */
.module:hover, .piste:hover, .faq-acc details[open] {
  background-image: linear-gradient(180deg, rgba(255, 255, 255, .06), rgba(255, 255, 255, 0) 62%);
}

/* Les deux bandes pleine largeur reçoivent leur propre halo, décalé de celui du corps : sans lui
   elles retombaient à plat au milieu d'une page qui, elle, respire. */
.bande-pipeline {
  background-image:
    radial-gradient(48rem 26rem at 18% 0%, color-mix(in srgb, var(--semi-labiale) 8%, transparent), transparent 62%),
    linear-gradient(180deg, rgba(255, 255, 255, .025), rgba(255, 255, 255, 0) 40%);
}
.souverainete-compte {
  background-image:
    radial-gradient(26rem 22rem at 80% 10%, color-mix(in srgb, var(--ouverture) 9%, transparent), transparent 65%);
}
/* Le héros : un halo derrière la capture, pour qu'elle se détache du fond au lieu d'y être posée. */
.hero-vue::before {
  content: ""; position: absolute; inset: -12% -8%; z-index: -1; border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--avancee) 12%, transparent), transparent);
}
/* Le pied, éclairé depuis le haut à gauche — repris de la référence `minimal-footer`. */
.pied {
  background-image:
    radial-gradient(40rem 18rem at 22% 0%, rgba(255, 255, 255, .05), transparent 70%);
}


/* ── Carrousel des forfaits par métier ──────────────────────────────────────
   Cinq cartes sur une seule ligne, qui coulissent. La grille en colonnes les empilait sur trois
   rangs ; alignées, elles se comparent d'un regard — c'est ce qu'on fait devant des forfaits.

   ⚠️ LE DÉFILEMENT NATIF RESTE. Les flèches ne sont qu'un raccourci : la molette, le doigt et le
   clavier continuent de fonctionner. Un carrousel qui n'obéit qu'à ses propres boutons est
   inutilisable au clavier et sur un pavé tactile. */
/* ⚠️ LES FLÈCHES SONT HORS DE LA PISTE, PAS PAR-DESSUS. Posées en absolu sur les bords, elles
   masquaient la première et la dernière carte — et la piste, elle, tranchait les cartes en deux au
   bord du cadre. Trois colonnes règlent les deux : la piste occupe la colonne du milieu, chaque
   flèche a la sienne, et plus rien ne se chevauche. */
.rail { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; align-items: center }
.rail .offres-grille {
  display: flex; overflow-x: auto;
  gap: 16px; margin: 0; padding: 4px 0 14px; scrollbar-width: thin;
  /* ⚠️ PAS DE `scroll-behavior: smooth` ICI. Avec lui, une affectation de `scrollLeft` démarre une
     animation qui se fait annuler — la piste revenait à zéro et les flèches semblaient mortes.
     Le glissement se demande en JavaScript, par `scrollBy({ behavior })`, qui est l'API faite pour
     ça et qui laisse le choix de l'animation à qui la déclenche. */
  /* `mandatory` et non `proximity` : le défilement s'ARRÊTE toujours sur une carte entière. Avec
     `proximity`, il pouvait s'immobiliser au milieu d'une carte — c'est ce qui la coupait. */
  scroll-snap-type: x mandatory;
}
/* Trois cartes pleines dans la largeur disponible, jamais deux et demie. La largeur se déduit de
   la piste et de l'écart : aucune valeur fixe ne survivrait à un redimensionnement. */
.rail .offres-grille > .offre { flex: 0 0 calc((100% - 32px) / 3); scroll-snap-align: start }
@media (max-width: 1100px) { .rail .offres-grille > .offre { flex-basis: calc((100% - 16px) / 2) } }
@media (max-width: 720px)  { .rail .offres-grille > .offre { flex-basis: 100% } }

.rail-b {
  width: 44px; height: 44px; display: grid; place-items: center;
  border: 1px solid var(--bd); border-radius: 999px; cursor: pointer;
  background: var(--s1); color: var(--tx); font-size: 20px; line-height: 1; padding: 0;
  transition: background .15s, border-color .15s, opacity .2s;
}
.rail-b:hover { background: var(--s2); border-color: var(--ac) }
.rail-b:focus-visible { outline: 2px solid var(--ac); outline-offset: 2px }
/* Désactivée, la flèche reste EN PLACE : la masquer ferait sauter la piste de 56 px à chaque bout
   de course. On l'estompe, la colonne garde sa largeur. */
.rail-b[disabled] { opacity: .25; cursor: default }
/* Au doigt, on fait glisser : les flèches ne servent plus, et elles prendraient de la largeur à
   des cartes qui n'en ont déjà pas assez. */
@media (max-width: 720px) {
  .rail { grid-template-columns: minmax(0, 1fr) }
  .rail-b { display: none }
}

/* ─── Liste de diffusion, dans le pied ────────────────────────────────────────
   Elle vit ENTRE la nav du pied et la barre du bas, sur toute la largeur : ailleurs — dans une
   colonne de liens — un champ de saisie se lit comme un champ de recherche, et personne ne le
   remplit. Ici, la ligne de promesse et le champ se lisent ensemble. */
.pied-liste { border-top: 1px solid var(--regie); padding: 22px 0 }
.pied-liste .inner {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px 32px; align-items: center;
}
.pl-titre { font-family: var(--titre); font-size: 15px; font-weight: 600; margin: 0 0 2px; color: var(--craie) }
.pl-mots .fine { margin: 0 }
.pl-form { display: flex; gap: 8px; position: relative }
.pl-form input[type="email"] {
  min-width: 240px; padding: 9px 12px; font: inherit; font-size: 14px;
  color: var(--craie); background: var(--pellicule);
  border: 1px solid var(--regie); border-radius: var(--r);
}
.pl-form input[type="email"]::placeholder { color: var(--murmure) }
/* ⚠️ AUCUNE RÈGLE DE FOCUS ICI, et c'est délibéré : la règle globale (`:focus-visible`, plus haut)
   pose déjà un contour blanc cohérent sur tout le site. En écrire une seconde pour ce seul champ
   donnerait au dernier élément atteignable au clavier une couleur qu'il est le seul à porter. */
/* La note vit sous les deux colonnes : elle porte le consentement, et une note de consentement
   tronquée dans une colonne étroite ne se lit pas. */
.pl-note { grid-column: 1 / -1; margin: 2px 0 0; font-size: 12px }
.pl-note.ok { color: var(--ouverture) }
.pl-note.ko { color: var(--rouge) }

/* Masqué à l'œil, gardé pour les lecteurs d'écran. `clip-path` et non `display:none` : ce dernier
   retire l'élément de l'arbre d'accessibilité, ce qui priverait le champ de son libellé. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

@media (max-width: 720px) {
  .pied-liste .inner { grid-template-columns: minmax(0, 1fr) }
  .pl-form input[type="email"] { min-width: 0; flex: 1 }
}
