
/* ⚠️ ADRESSE DE L APPLICATION EN DUR DANS LES PAGES HTML.
   Le site et l application vivent sur deux sous-domaines differents. Les
   liens vers /carte, /recherche, /c/... et /p/... doivent donc etre ABSOLUS :
   ecrits en relatif, ils pointaient vers le domaine du SITE et rendaient 404.
   Treize liens casses trouves en parcourant le site publie, pas en relisant
   le code — un audit par echantillon ne les avait pas vus.
   Le jour du vrai domaine : chercher app.jjb.5-189-186-222.sslip.io dans
   site/*.html et remplacer partout. */
/* ==========================================================================
   JJB-VRAIVEX — feuille de style du site de presentation.

   THESE : le jiu-jitsu n'est pas une liste de mouvements, c'est une CARTE du
   sol. Tout le site est construit dessus — le heros l'affirme, la progression
   par ceinture la demontre, le graphe la rend visible.

   REGISTRE (2026-09-03, deuxieme passe) : le registre precedent — fond
   marine, accent bleu, rangees de compteurs, cartes arrondies a filet
   colore — a ete juge « trop IA » a raison, et pas seulement sur la
   couleur. Ce registre-ci vient de la culture visuelle reelle du jiu-jitsu
   (marques de kimono : Shoyoroll, Scramble) : noir chaud, UNE seule
   couleur criarde (le rouge oxyde), typographie massive, blocs en ecusson
   plutot que cartes arrondies. Aucun bleu, aucun violet, sauf quand ils
   sont la donnee d'une ceinture.

   COULEURS ET JETONS : copies EXACTEMENT de src/app/globals.css, seule
   source de la palette. Ne jamais declarer une couleur ici. Registre
   unique, jamais prefers-color-scheme.

   ⚠️ REGLE 1 — L'accent est --vif (rouge oxyde). Jamais le bleu. Le seul
   bleu/violet tolere sur une page est celui d'une CEINTURE : une donnee.
   ⚠️ REGLE 2 — Sur un aplat --vif, le texte est --sur-vif (NOIR), jamais
   blanc : mesure, blanc fait 3,95:1 (sous le seuil), noir fait 4,99:1.
   ⚠️ REGLE 3 — --rayon vaut 0. Des ecussons, pas des cartes arrondies.
   ⚠️ REGLE 4 — Le corps de texte est en SERIF (--corps). --sans porte
   l'interface courte (nav, boutons, etiquettes de menu) ; --code porte les
   DONNEES (compteurs, tableaux, codes) — jamais la prose.
   ⚠️ REGLE 5 — --trait-fort est un FILET, jamais du texte (2,3:1 sur le
   fond). Pour un texte discret, --texte-discret (5,5:1, le plancher).
   ========================================================================== */

:root {
  /* ⚠️ LE SITE EST PASSE EN CLAIR LE 2026-09-04, PAS L'APPLICATION.
     Ce bloc n'est donc PLUS une copie de src/app/globals.css : il en est
     l'inverse, et les deux vont diverger. Le dire ici plutot que de laisser
     la phrase « copie exacte » mentir a la prochaine relecture.
     Raison : « le noir tue les yeux » sur un texte long -- du #EDEAE3 sur du
     #0B0B0B, c'est 17:1, le contraste maximum, et c'est ce qui provoque
     l'effet de halo quand on lit plusieurs paragraphes.
     ⚠️ CHAQUE VALEUR CI-DESSOUS A ETE MESUREE AVANT D'ETRE ECRITE, pas
     choisie a l'oeil. Les ratios sont donnes en commentaire.
     ⚠️ LE ROUGE A DU CHANGER : #E8452C ne donne que 3,63:1 sur un fond
     clair, sous le seuil de 4,5. #C2341F donne 5,07 en texte et accepte du
     blanc par-dessus a 5,52. Ne pas revenir a l'ancien rouge pour du TEXTE
     sur clair sans remesurer. */
  --fond:         #F7F5F1;   /* creme, pas blanc pur : moins de halo encore */
  --carte:        #FFFFFF;
  --carte-haute:  #FFFFFF;
  --trait:        #E2DDD4;
  --trait-fort:   #C8C1B5;
  --texte:         #1A1A1A;  /* 15,98:1 sur le fond */
  --texte-faible:  #5C574F;  /*  6,58:1 */
  --texte-discret: #6E6960;  /*  5,01:1, le plancher */
  --texte-encre:   #F7F5F1;

  --vif:     #C2341F;   /* 5,07:1 en texte sur le fond */
  --sur-vif: #FFFFFF;   /* ⚠️ le seul texte admis sur un aplat --vif (5,52:1) */

  --sur-aplat:        #FFFFFF;
  --c-blanche:        #C8C1B5;   /* la ceinture blanche a besoin d'un
                                    contour visible sur un fond clair */
  --c-blanche-clair:  #6E6960;
  --c-bleue:          #2F5FA6;
  --c-bleue-clair:    #7BA3DC;
  --c-violette:       #6B4C93;
  --c-violette-clair: #B79BD6;
  --c-marron:         #7A4A2B;
  --c-marron-clair:   #C4855A;
  --c-noire:          #1A1A1A;
  --c-noire-clair:    #5C574F;
  --or:               #8A6410;

  --risque-1:      #2F7A45;   /* 4,83:1 sur le fond */
  --risque-2:      #8A6410;   /* 4,93:1 */
  --risque-3:      #6E6960;   /* 5,01:1 */
  --risque-3-fond: #F0EBE2;
  --focus: #C2341F;

  --titre: "Archivo Black", Impact, "Arial Black", system-ui, sans-serif;
  --corps: "Source Serif 4", Georgia, "Times New Roman", serif;
  --sans:  "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --code:  "Courier Prime", ui-monospace, "SF Mono", "Cascadia Mono", Menlo,
           monospace;

  --rayon:   0px;
  --cible:   2.75rem;   /* 44px : le minimum tactile, jamais moins */
  --colonne: 72rem;
  --lecture: 38rem;     /* la colonne de lecture : ~68 signes */

  /* --- Propre au site : echelle plus fine, construite SUR le plancher de
     globals.css (--t-plancher, 13px, 5,5:1 avec --texte-discret). Rien ne
     descend sous --t-2xs, qui EST ce plancher. -------------------------- */
  --t-2xs: 0.8125rem;  /* 13px = --t-plancher de globals.css */
  --t-xs:  0.875rem;   /* 14px = --t-petit */
  --t-sm:  0.9375rem;  /* 15px = --t-moyen */
  --t-md:  1.0625rem;  /* 17px = --t-corps, taille du body */
  --t-lg:  1.3rem;
  --t-xl:  1.75rem;
  --t-2xl: 2.4rem;
  --t-3xl: clamp(2.5rem, 11vw, 4.25rem);   /* = --t-h1 de globals.css */
  --t-geant: clamp(4.6rem, 21vw, 9.5rem);  /* le chiffre unique du heros */

  --e1: .4rem;  --e2: .8rem;  --e3: 1.3rem;
  --e4: 2rem;   --e5: 3.2rem; --e6: 5rem;  --e7: 7rem;
}

*, *::before, *::after { box-sizing: border-box; }
html { color-scheme: dark; -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--fond); color: var(--texte);
  font-family: var(--corps); font-size: var(--t-md); line-height: 1.62;
  -webkit-font-smoothing: antialiased; overflow-x: hidden;
}
/* ⚠️ height:auto est OBLIGATOIRE ici. Sans lui, un <img width height> dont
   aucune regle plus specifique ne fixe la hauteur garde la hauteur EN PIXELS
   de l'attribut HTML alors que max-width retrecit la largeur — l'image
   s'etire verticalement au lieu de se mettre a l'echelle. Trouve sur
   .ceintures-photo a 390px : 346px de large pour 933px de haut, image
   ecrasee sur toute la hauteur de l'ecran. Les regles qui fixent deja leur
   propre hauteur (.hero__fond img, .photo-large img, .photo-bandeau img)
   restent prioritaires : plus specifiques, elles l'emportent dans la
   cascade quel que soit l'ordre. */
img, svg { max-width: 100%; height: auto; display: block; }
h1, h2, h3, p, ul, ol, dl, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: var(--vif); }
a:hover { color: var(--texte); }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

.wrap { max-width: var(--colonne); margin-inline: auto; padding-inline: var(--e3); }
@media (min-width: 700px) { .wrap { padding-inline: var(--e4); } }
.colonne-lecture { max-width: var(--lecture); }

.skip-link {
  position: absolute; left: -999px; top: auto; z-index: 100;
  background: var(--vif); color: var(--sur-vif); font-family: var(--sans);
  font-weight: 700; padding: var(--e2) var(--e3); border-radius: var(--rayon);
}
.skip-link:focus { left: var(--e3); top: var(--e3); }

/* --- En-tete -------------------------------------------------------------
   Bandeau plein, le contraste ne depend jamais d'une photo.
   ⚠️ Collant (position:sticky), aux deux formats. C'est une encyclopedie
   qu'on parcourt en longueur — la page d'accueil seule fait plus de 500
   lignes, les autres pages renvoient vers des ancres (#etat-du-contenu,
   #plateau-bleue, #niveaux-titre...) qu'on veut pouvoir rouvrir sans
   remonter en haut de page a la main. Le cout habituel d'un en-tete
   collant — de la hauteur volee en permanence sur un telephone — a motive
   tout le reste de ce chantier : l'en-tete mobile ne fait plus qu'une
   ligne (moins de 64px, mesure dans le rapport), donc le coller en
   permanence ne mange plus qu'une bande fine, pas les deux tiers du
   premier ecran comme avant. Le meme choix vaut pour l'ordinateur : la
   colonne de lecture (--lecture, 38rem) fait defiler des pages longues, la
   nav qui reste a portee compense largement les quelques pixels pris. */
.site-header {
  position: sticky; top: 0; z-index: 30;
  background: var(--fond); border-bottom: 1px solid var(--trait);
}
/* ⚠️ TROIS enfants directs sous 1180px depuis le 2026-09-04 : .wordmark,
   a.entete-inscription (le bouton d'inscription permanent, ajoute parce
   qu'aucun appel a l'action n'etait atteignable sur mobile sans ouvrir le
   menu) et details.nav-mobile. Au-dessus de 1180px, le bouton disparait et
   il n'en reste que deux, comme avant.
   ⚠️ CE TROISIEME ENFANT A FAIT DEBORDER L'EN-TETE : mesure a 390px,
   scrollWidth 419 pour 390 disponibles, sur les sept pages. Correctif juste
   en dessous : sous 430px le nom de la marque s'efface et le signe reste
   seul, ce qui libere la centaine de pixels manquante. Ne pas retirer cette
   regle sans remesurer.
   Plus de flex-wrap : sur une seule ligne, rien ne doit jamais se replier
   au hasard ici. */
.site-header .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e2); padding-block: var(--e1);
}
/* Sous 430px, le nom ecrit cede la place : le signe suffit a ramener a
   l'accueil, et les trois elements tiennent alors sur la ligne. Le lien
   garde sa cible de 44px et son nom accessible (le texte reste dans le
   DOM pour les lecteurs d'ecran, il n'est que masque visuellement). */
@media (max-width: 430px) {
  .site-header .wrap { gap: var(--e1); }
  .wordmark__texte {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
}
@media (min-width: 1180px) {
  /* L'en-tete "respire" a partir de la ou il a la place : plus de padding
     vertical, logo et nom agrandis. Serre a 1280px etait un des deux
     defauts releves ; ceci en est le correctif direct.
     ⚠️ ET MOINS DE PADDING HORIZONTAL, mesure : a 1180 px exactement, le
     bloc « Se connecter / Creer un compte » depassait de 5 px et TOUTES les
     pages debordaient. Le defaut etait invisible parce qu'on mesurait a 390
     et a 1200, jamais au point de bascule lui-meme. Rendre 24 px de chaque
     cote suffit largement, et ne se voit pas : l'en-tete est la seule bande
     concernee, le contenu garde sa gouttiere. */
  .site-header .wrap { padding-block: var(--e3); padding-inline: 1.25rem; }
}
.wordmark {
  display: flex; align-items: center; gap: .55rem; text-decoration: none;
  color: var(--texte); font-family: var(--titre); font-weight: 800;
  font-size: var(--t-lg); letter-spacing: .01em; text-transform: uppercase;
  min-height: var(--cible);
}
@media (min-width: 1180px) {
  /* Bump modeste : seul le signe grandit (plus de poids visuel), le texte
     garde sa taille — l'agrandir aussi (essaye d'abord) ne laissait plus
     assez de largeur pour la nav + les actions de compte sur une seule
     ligne entre 900 et ~1050px, mesure au navigateur. L'air demande par la
     consigne vient du padding vertical du bandeau (juste au-dessus) et du
     filet qui separe nav et compte (plus bas), pas d'un logo plus large. */
  .wordmark { gap: .7rem; }
  .wordmark__mark { width: 1.75rem; height: 1.75rem; }
}
.wordmark em { font-style: normal; }
/* ⚠️ Le nom tient dans UN SEUL enfant flex (.wordmark__texte / .footer-
   marque__mot). Si "JJB" (texte nu) et "-Vraivex" (dans <em>) restent deux
   enfants directs separes de ce conteneur flex, le `gap` du conteneur
   s'imprime ENTRE EUX — entre le "B" et le tiret — et affiche
   "JJB -VRAIVEX" : une espace parasite que rien dans le texte source ne
   contient, purement due au flex-gap qui traite <em> comme un item a part. */
.wordmark__texte { display: inline-block; }
/* Le vrai signe (img/signe.svg) : deux positions reliees, depart plein /
   arrivee creuse — pas un carre CSS improvise. Decoratif (alt vide) : le
   nom qui suit dans le texte porte deja l'information. */
.wordmark__mark { width: 1.5rem; height: 1.5rem; flex: none; display: block; }

/* --- Navigation principale + mega-menu -----------------------------------
   Zero dependance : le mega-menu est un <details>/<summary> natif — focus et
   activation clavier (Entree/Espace) viennent du navigateur, sans une ligne
   de JS. Seule la fermeture a l'Echap n'a pas d'equivalent natif ; un tout
   petit script (une dizaine de lignes, en fin de <body>, sans dependance)
   comble ce seul manque. C'est le seul JavaScript du site. */
/* ⚠️ Empilee par defaut (une entree par ligne, alignee a gauche) : c'est le
   contenu du tiroir mobile, voir plus bas. A partir de 1180px elle redevient
   la rangee horizontale d'origine.
   ⚠️ `.main-nav > ul`, PAS `.main-nav ul` : un descendant, pas un enfant
   direct, aurait aussi cible ul.mega__liste (les listes du mega-menu,
   imbriquees plus bas dans le meme <nav>) — meme les yeux dessus, ca ne se
   voit pas tant que les deux regles disent la meme chose (flex-direction:
   column ici comme sur .mega__liste), et .main-nav ul gagne quand meme sur
   .mega__liste a specificite egale de classe (0,1,0) parce qu'elle ajoute
   l'element `ul` (0,1,1). Le bug n'est devenu visible qu'a l'ouverture du
   mega-menu a 1180px+ : la ligne juste en dessous y passe flex-direction a
   row, qui a alors ECRASE le column de .mega__liste — chaque colonne du
   panneau s'est retrouvee empilee HORIZONTALEMENT, tout le texte
   superpose sur une seule ligne. Mesure et corrige dans ce chantier. */
.main-nav > ul {
  display: flex; flex-direction: column; gap: var(--e1);
  margin: 0; padding: 0; list-style: none;
}
@media (min-width: 1180px) {
  /* ⚠️ nowrap, pas wrap : une rangee horizontale qui se replie encore
     serait exactement le defaut mesure sur l'ancien en-tete (repli au
     hasard par flex-wrap). Si ca ne tient pas, ca doit deborder de facon
     visible (attrape par la mesure automatique) pour etre corrige a la
     source — jamais se cacher dans un repli silencieux. */
  .main-nav > ul { flex-direction: row; flex-wrap: nowrap; align-items: center; }
}
.main-nav a {
  display: flex; align-items: center; min-height: var(--cible);
  padding-inline: var(--e1); text-decoration: none; color: var(--texte-faible);
  font-family: var(--sans); font-weight: 600; font-size: var(--t-xs);
  letter-spacing: .04em; text-transform: uppercase; border-bottom: 2px solid transparent;
  /* ⚠️ 44 px dans les DEUX sens, garanti par le plancher ci-dessous et non
     plus par le padding : un libelle court comme « Tarifs » ne faisait que
     36 px de large avec un simple padding — mesure au navigateur sur le
     site publie, invisible en relisant le CSS. min-width est la garantie
     dure, quel que soit le padding choisi par ailleurs. */
  min-width: var(--cible);
  /* Aligne a gauche : empile proprement dans le tiroir mobile. En rangee
     horizontale (1180px+) la difference avec un centrage est invisible, la
     largeur de la boite suivant deja le contenu. */
  justify-content: flex-start;
}
.main-nav a:hover { color: var(--texte); border-bottom-color: var(--trait-fort); }
.main-nav a[aria-current="page"] { color: var(--texte); border-bottom-color: var(--vif); }

/* Pas de position:relative ici : le panneau doit deborder ce <li>, pas s'y
   coller. Son bloc conteneur reste .site-header (voir .mega__panneau). */
.main-nav li.mega-item { position: static; }
.main-nav summary {
  display: flex; align-items: center; gap: .3rem; min-height: var(--cible);
  padding-inline: var(--e2); cursor: pointer; list-style: none;
  color: var(--texte-faible); font-family: var(--sans); font-weight: 600; font-size: var(--t-xs);
  letter-spacing: .04em; text-transform: uppercase; border-bottom: 2px solid transparent;
  -webkit-tap-highlight-color: transparent;
}
.main-nav summary::-webkit-details-marker { display: none; }
.main-nav summary::marker { content: ""; }
.main-nav summary:hover { color: var(--texte); border-bottom-color: var(--trait-fort); }
details.mega[open] > summary { color: var(--texte); border-bottom-color: var(--vif); }
.mega__caret { font-size: .65em; transition: transform .15s ease; }
details.mega[open] .mega__caret { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .mega__caret { transition: none; } }

/* ⚠️ Le panneau est TOUJOURS plein bord, d'un bord de fenetre a l'autre —
   jamais une boite flottante sous "Explorer". En dessous de 1100px il reste
   dans le flux (marge negative pour annuler le padding du .wrap ancetre,
   voir plus bas) ; a partir de 1100px il passe en position absolute contre
   .site-header (voir plus bas), le seul ancetre positionne restant une fois
   .mega-item repasse en position:static. Son CONTENU, lui, ne colle jamais
   au bord : il vit dans un .wrap interne — la meme classe que le reste du
   site — pour retomber exactement sur la colonne de page. Un panneau qui
   deborde la fenetre mais aligne son contenu a l'air concu ; un panneau qui
   flotte au hasard a l'air d'un accident. */
.mega__panneau {
  background: var(--carte-haute);
  border-top: 2px solid var(--trait-fort);
  border-bottom: 1px solid var(--trait-fort);
  margin: var(--e2) calc(var(--e3) * -1) 0;
}
@media (min-width: 700px) {
  .mega__panneau { margin-inline: calc(var(--e4) * -1); }
}
/* ⚠️ .site-header .wrap (plus haut dans ce fichier) cible TOUT .wrap
   descendant de .site-header — donc aussi celui-ci, qui en est un puisque
   la structure est site-header > .wrap > nav > ... > .mega__panneau > .wrap.
   Meme specificite (deux classes) que la regle ci-dessous : le display
   passe bien en grid (derniere regle du fichier gagne sur cette proprietee),
   mais align-items:center et justify-content:space-between de la regle du
   header, eux, ne sont touches par aucune declaration ici — ils continuaient
   donc de s'appliquer MALGRE le display:grid, et centraient chaque colonne
   sur la hauteur de la plus haute au lieu de caler tous les titres en haut.
   D'ou les quatre titres a des hauteurs differentes. Il faut les reprendre
   explicitement, meme si la valeur semble redondante avec le defaut grid. */
.mega__panneau > .wrap {
  display: grid; gap: var(--e4); grid-template-columns: 1fr;
  align-items: start; justify-content: normal;
  padding-block: var(--e4);
}
@media (min-width: 700px) {
  .mega__panneau > .wrap { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 1180px) {
  .mega__panneau {
    position: absolute; inset-inline: 0; top: 100%; margin: 0;
    box-shadow: 0 24px 48px rgba(0,0,0,.6); z-index: 30;
  }
}
@media (min-width: 1180px) {
  .mega__panneau > .wrap {
    grid-template-columns: 1.1fr 1fr 1fr 1.2fr; gap: var(--e5); padding-block: var(--e5);
    /* stretch (pas start) ICI : la ligne de grille n'a qu'une hauteur,
       dictee par la colonne la plus longue (Par technique, 8 entrees) — les
       colonnes plus courtes laissaient donc un grand vide sous leur contenu.
       stretch etire la BOITE de chaque colonne sur toute cette hauteur (le
       contenu, lui, part toujours du haut : aucun impact sur l'alignement
       des titres) ; les filets verticaux ci-dessous s'etirent avec elle et
       transforment ce vide en separation voulue plutot qu'en espace mort. */
    align-items: stretch;
  }
  .mega__col:not(:last-child) { border-right: 1px solid var(--trait); }
  .mega__col:not(.mega__col--appel) { padding-right: var(--e4); }
}
/* ⚠️ Ces deux min-width:0 n'existaient pas avant ce chantier et sont sans
   effet visuel tant que tout tient deja (colonnes, alignement, filets :
   identiques avec ou sans eux, revérifié). Ils sont devenus necessaires
   quand la nav a gagne un niveau d'ancetres flex supplementaire (le tiroir
   mobile, .nav-mobile__panneau/.nav-mobile__interieur, voir plus bas) :
   measure au navigateur, ouvrir "Explorer" a 1280px debordait alors de
   ~1800px sans que rien ne le signale a l'oeil (le panneau lui-meme garde
   sa largeur ; c'est son CONTENU qui deborde). Cause exacte : un flex/grid
   item a pour min-width par defaut "auto", qui vaut la taille min-content
   de son contenu — et du texte en white-space:nowrap (regle 2 du fichier
   de la reprise precedente, pour qu'aucun libelle ne casse) n'a PAS de
   min-content plus petit que sa largeur pleine, puisqu'il ne peut pas se
   couper. Empile sur plusieurs niveaux flex/grid embo tes, cette largeur
   pleine remonte comme un plancher dur a chaque etage, colonne du mega
   comprise, jusqu'a forcer les 4 colonnes a s'additionner sur ~2900px au
   lieu de se partager 1152px. min-width:0 casse ce plancher aux deux points
   ou il se former ; white-space:nowrap continue seul a empecher la casse
   de ligne, comme avant. */
.mega__col { min-width: 0; }
.mega__titre {
  font-family: var(--code); font-size: var(--t-2xs); letter-spacing: .1em;
  text-transform: uppercase; color: var(--or); margin: 0 0 var(--e2);
  white-space: nowrap;
}
.mega__liste { display: flex; flex-direction: column; gap: .05rem; margin: 0; padding: 0; list-style: none; }
/* ⚠️ Sans width:100% explicite, un <li> reste "list-item" a l'ecran et ne
   s'etire pas sur toute la largeur de la colonne flex malgre align-items
   stretch : chaque ligne se recroqueville sur son contenu et le numero
   perd son alignement a droite. min-width:0 est l'autre moitie du
   correctif juste au-dessus (.mega__col) : sans elle, ce <li> en
   white-space:nowrap remonte sa largeur pleine comme plancher dur a
   travers .mega__liste (flex) jusqu'a .mega__col (item de grille) et
   fait deborder tout le panneau — voir le commentaire juste plus haut. */
.mega__liste li { width: 100%; min-width: 0; }
/* Deux colonnes par ligne — le nom, puis le compteur — jamais un flottement :
   justify-content les pousse aux deux bords, align-items:baseline les pose
   sur la meme ligne de base plutot que de les centrer sur une hauteur de
   ligne qui grandirait si le nom cassait. white-space:nowrap est la garantie
   dure : aucun libelle ne peut plus se casser en deux lignes ici, quelle que
   soit la largeur — les colonnes ont ete elargies (voir .mega__panneau) pour
   qu'aucun libelle du catalogue ne l'atteigne jamais. */
.mega__liste a, .mega__ligne {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--e2);
  min-height: var(--cible); padding-inline: .2rem; font-size: var(--t-sm);
  font-family: var(--sans); color: var(--texte); text-decoration: none; border-radius: var(--rayon);
  white-space: nowrap;
}
.mega__liste a:hover { color: var(--vif); }
/* La pastille de ceinture n'a pas de ligne de base (ce n'est pas du texte) :
   elle reste centree verticalement sur le nom plutot que calee dessus. */
.mega__liste--ceintures a { gap: .65rem; align-items: center; }
.mega__liste--type .mega__ligne { color: var(--texte-faible); }
.mega__n {
  font-family: var(--code); font-size: var(--t-2xs); color: var(--texte-discret);
  font-variant-numeric: tabular-nums; flex: none;
}
.mega__voir {
  display: inline-flex; align-items: center; min-height: var(--cible);
  margin-top: .1rem; font-size: var(--t-xs); font-family: var(--sans); font-weight: 700;
  color: var(--vif); text-decoration: none; white-space: nowrap;
}
.mega__voir:hover { color: var(--texte); }
/* Le bouton de la colonne d'appel ne casse jamais non plus, et sa bordure
   ne colle plus au bord du panneau : la colonne a sa propre marge basse. */
.mega__col--appel { border-top: 1px solid var(--trait); padding-top: var(--e3); padding-bottom: .2rem; }
.mega__col--appel .btn { white-space: nowrap; }
@media (min-width: 1180px) {
  /* Pas de border-left ici : la regle generique .mega__col:not(:last-child)
     ci-dessus dessine deja le filet a gauche de cette colonne (elle est la
     derniere), etire sur toute la hauteur de la ligne via align-items:stretch.
     Une deuxieme bordure ici aurait dessine un double filet cote a cote. */
  .mega__col--appel { border-top: none; padding: 0 0 0 var(--e4); }
}
.mega__accroche {
  font-family: var(--titre); font-weight: 700; font-size: var(--t-lg);
  text-transform: uppercase; line-height: 1.05; margin: 0 0 var(--e2);
}
.mega__texte { font-family: var(--sans); font-size: var(--t-sm); color: var(--texte-faible); line-height: 1.6; margin: 0 0 var(--e3); }

/* --- Navigation mobile : le tiroir plein-largeur --------------------------
   Meme parti pris que le mega-menu : <details>/<summary> natif, zero JS pour
   ouvrir/fermer/naviguer au clavier — seul l'Echap (script en fin de body,
   deja necessaire pour le mega-menu) est etendu aux deux composants.

   ⚠️ En dessous de 1100px, l'en-tete n'a plus que DEUX enfants dans .wrap :
   le logo et ce <details>. Toute la nav (Explorer + les 3 liens) et les
   deux actions de compte vivent dans son panneau — un tiroir plein-largeur,
   pas une boite flottante, choisi plutot qu'un tiroir lateral etroit : le
   mega-menu qu'il contient a deja besoin de toute la largeur pour ses
   quatre familles empilees (voir plus haut), un tiroir a 80% de largeur
   l'aurait re-comprime inutilement. A partir de 1100px, ce meme <details>
   devient invisible en tant que tel : son declencheur disparait et son
   panneau repasse en ligne, a cote du logo — exactement l'en-tete
   d'origine, juste reorganise pour porter aussi le mobile. */
.nav-mobile { position: static; }

.nav-toggle {
  display: flex; align-items: center; gap: .5rem;
  min-width: var(--cible); min-height: var(--cible);
  padding-inline: var(--e2); cursor: pointer; list-style: none;
  color: var(--texte); font-family: var(--sans); font-weight: 700;
  font-size: var(--t-xs); letter-spacing: .04em; text-transform: uppercase;
  border: 1px solid var(--trait-fort); -webkit-tap-highlight-color: transparent;
}
.nav-toggle::-webkit-details-marker { display: none; }
.nav-toggle::marker { content: ""; }
.nav-toggle:hover { border-color: var(--texte-faible); }
details.nav-mobile[open] > .nav-toggle { border-color: var(--vif); color: var(--vif); }

/* L'icone : trois barres en CSS pur, pas un glyphe de police (rendu
   inconstant selon les systemes). Elle se change en croix a l'ouverture —
   meme logique que la rotation du chevron du mega-menu juste au-dessus. */
.nav-toggle__icone { position: relative; width: 1.1rem; height: .8rem; flex: none; }
.nav-toggle__icone span {
  position: absolute; left: 0; width: 100%; height: 2px; background: currentColor;
  transition: transform .15s ease, opacity .15s ease;
}
.nav-toggle__icone span:nth-child(1) { top: 0; }
.nav-toggle__icone span:nth-child(2) { top: 50%; margin-top: -1px; }
.nav-toggle__icone span:nth-child(3) { bottom: 0; }
details.nav-mobile[open] .nav-toggle__icone span:nth-child(1) { transform: translateY(.39rem) rotate(45deg); }
details.nav-mobile[open] .nav-toggle__icone span:nth-child(2) { opacity: 0; }
details.nav-mobile[open] .nav-toggle__icone span:nth-child(3) { transform: translateY(-.39rem) rotate(-45deg); }
@media (prefers-reduced-motion: reduce) { .nav-toggle__icone span { transition: none; } }

/* Le panneau : meme principe de bord-a-bord que .mega__panneau (plein
   bord, contenu recale dans un conteneur interne, .nav-mobile__interieur
   ci-dessous) — mais pas le meme mecanisme, voir pourquoi juste en dessous.
   ⚠️ Pas de marge negative ici, contrairement a .mega__panneau plus haut :
   celui-la en a besoin parce qu'il reste EN FLUX sous 1100px (la marge
   negative y annule le padding de l'ancetre .wrap pour tout de meme
   toucher les bords). Celui-ci est deja position:absolute + inset-inline:0
   a TOUTES les largeurs, ce qui suffit seul a toucher les bords — y ajouter
   la meme marge negative double le debordement (mesure : 21px de trop de
   CHAQUE cote a 390px, --e3 applique en plus d'un inset deja a 0). */
.nav-mobile__panneau {
  position: absolute; inset-inline: 0; top: 100%;
  background: var(--carte-haute); border-top: 1px solid var(--trait-fort);
  box-shadow: 0 24px 48px rgba(0,0,0,.6);
  max-height: calc(100vh - 4rem); overflow-y: auto; z-index: 1;
}

.nav-mobile__interieur {
  max-width: var(--colonne); margin-inline: auto; padding: var(--e4) var(--e3);
  display: flex; flex-direction: column; gap: var(--e4);
}
@media (min-width: 700px) { .nav-mobile__interieur { padding-inline: var(--e4); } }

@media (min-width: 1180px) {
  /* ⚠️ 1100px, pas 900 : mesure au navigateur, une seule ligne avec le
     logo + les 4 items de nav + les 2 actions de compte ne tenait pas avant
     ~1090px avec un espacement qui respire encore (voir le repli mesure
     dans le rapport). Comme le panneau du mega-menu passait deja en
     4 colonnes a 1100px (regle plus bas, inchangee), les deux seuils sont
     fusionnes en un seul : sous 1100px, tout — y compris "Explorer" —
     reste dans le traitement empile/tiroir deja valide a 390 et 768px ;
     a partir de 1100px, tout bascule ensemble (nav en ligne, mega flottant
     a 4 colonnes). Aucune des quatre largeurs demandees (390/768/1024/1280)
     ne tombe dans l'ancien entre-deux 900-1099 : rien de deja verifie n'est
     donc perdu, l'intervalle est simplement retire.
     Le tiroir cesse d'en etre un : plus de declencheur, la nav et les
     actions de compte remises en ligne a cote du logo.
     ⚠️ Ceci suppose que details.nav-mobile porte l'attribut [open] — un
     display:flex ne suffit pas a le forcer soi-meme : mesure au navigateur,
     Chrome masque le contenu non ouvert d'un <details> par un mecanisme
     interne (une boite ::details-content sous content-visibility:hidden)
     qu'aucune regle CSS posee sur un DESCENDANT ne peut lever — le display
     qu'on lui donne ici s'applique bien, mais a un noeud que le navigateur
     retire quand meme du rendu tant que [open] est absent. Seul l'attribut
     natif fait sortir le contenu de cet etat ; le script en fin de body le
     pose synchroniquement au meme seuil (et le retire en dessous), avant la
     premiere peinture — voir son commentaire. */
  .nav-toggle { display: none; }
  .nav-mobile__panneau {
    display: flex; position: static; margin: 0;
    background: none; border: 0; box-shadow: none;
    max-height: none; overflow: visible;
  }
  .nav-mobile__interieur {
    flex-direction: row; align-items: center; gap: var(--e3);
    max-width: none; margin: 0; padding: 0;
  }
  /* Plus de retrecissement silencieux : si ca ne tient pas, ca doit
     deborder de facon mesurable (voir le commentaire sur .main-nav ul plus
     haut), pas se comprimer jusqu'a casser un libelle. */
  .wordmark, .main-nav, .auth-row { flex-shrink: 0; }
}

/* --- Connexion / inscription : vers l'application ------------------------
   L'application (src/) n'a pas encore de parcours de connexion construit —
   /connexion est deja la cible documentee d'une redirection reelle
   (src/app/moi/page.tsx). On y pointe donc les deux liens.
   ⚠️ Separation franche d'avec la nav du site : un filet horizontal au-
   dessus dans le tiroir mobile (les deux familles de gestes ne se
   confondent pas, meme empilees), vertical a cote du logo a partir de
   1100px — jamais un simple espace, un vrai trait, --trait-fort comme le
   reste du registre (regle 5 : un filet, jamais du texte). */
.auth-row {
  display: flex; align-items: center; gap: var(--e2); flex-wrap: nowrap;
  border-top: 1px solid var(--trait-fort); padding-top: var(--e4);
}
@media (min-width: 1180px) {
  .auth-row {
    border-top: 0; border-left: 1px solid var(--trait-fort);
    padding-top: 0; padding-left: var(--e3);
  }
}
.auth-link {
  display: inline-flex; align-items: center; min-height: var(--cible);
  padding-inline: .4rem; color: var(--texte-faible); text-decoration: none;
  font-family: var(--sans); font-size: var(--t-sm); font-weight: 600;
}
.auth-link:hover { color: var(--texte); }
.btn--small { padding-inline: var(--e2); font-size: var(--t-xs); }

/* --- Le heros : une photographie, pas un aplat -------------------------- */
.hero {
  position: relative; isolation: isolate;
  display: flex; align-items: flex-end;
  padding-block: var(--e7) var(--e5); overflow: hidden;
}
/* ⚠️ La hauteur pleine page n'appartient QU'AU heros qui porte une
   photographie. Sans elle, min-height: min(92vh, 46rem) donnait 736 px de
   noir vide sur un telephone de 844 px de haut, avec le titre flottant au
   milieu de rien — mesure faite sur /confidentialite.html. Cinq pages sur
   sept sont dans ce cas : elles n'ont pas de .hero__fond.
   La regle suit donc la PRESENCE DE L'IMAGE, pas le nom de la page : une
   page qui gagne une photo demain reprend sa hauteur toute seule, une page
   qui la perd cesse de reserver du vide. */
.hero:has(.hero__fond) { min-height: min(92vh, 46rem); }
.hero__fond { position: absolute; inset: 0; z-index: -2; }
/* ⚠️ La photo a ete cadree sur un tatami bleu vif pour l'ancien registre
   marine ; sur fond noir-rouge, ce bleu lit comme un accent concurrent du
   rouge — exactement l'erreur que la regle 1 interdit. On ne regenere pas
   l'image (elle existe, elle est reelle) : on la desature et on l'assombrit
   au filtre pour qu'elle redevienne une texture sombre, pas une couleur. */
.hero__fond img {
  width: 100%; height: 100%; object-fit: cover;
  /* ⚠️ PLUS DE FILTRE DE DESATURATION. Les images ont ete REGENEREES dans ce
     registre — noirs chauds, un seul accent rouge oxyde, clair-obscur dur.
     Les desaturer, comme on le faisait pour rattraper des images produites
     pour l ancien fond marine, les transformait en boue grise : une
     photographie maquillee au filtre CSS n est plus une photographie. */
}
/* Le voile : sans lui le texte se pose sur une zone claire de la photo et
   devient illisible selon la largeur. Deux couches, une verticale pour le bas
   de page, une laterale pour la colonne de texte. color-mix() reste attache
   au jeton --fond : si le fond change de couleur, le voile suit. */
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(to top,
      var(--fond) 6%,
      color-mix(in oklab, var(--fond) 88%, transparent) 40%,
      color-mix(in oklab, var(--fond) 40%, transparent) 80%),
    linear-gradient(to right,
      color-mix(in oklab, var(--fond) 82%, transparent) 0%,
      color-mix(in oklab, var(--fond) 60%, transparent) 42%,
      color-mix(in oklab, var(--fond) 20%, transparent) 78%,
      transparent 100%);
}
.eyebrow {
  display: inline-block; font-family: var(--code); font-size: var(--t-2xs);
  letter-spacing: .16em; text-transform: uppercase; color: var(--or);
  margin-bottom: var(--e3);
}
.hero h1 {
  font-family: var(--titre); font-weight: 800; font-size: var(--t-3xl);
  line-height: .92; letter-spacing: -.01em; text-transform: uppercase;
  text-wrap: balance; max-width: 21ch; margin-bottom: var(--e3);
}
/* ⚠️ REGLE 4 : le titre deborde volontairement de la colonne de lecture
   (--lecture, 38rem) — c'est le geste qui distingue ce registre d'une
   grille sagement rangee. Pas de debordement de VIEWPORT pour autant :
   verifie a 390 et 1200px, voir le rapport. */
.hero h1 em { font-style: normal; color: var(--vif); }
.lead {
  font-size: var(--t-lg); color: var(--texte-faible); max-width: 34rem;
  line-height: 1.5;
}
.cta-row { display: flex; flex-wrap: wrap; gap: var(--e2); margin-top: var(--e4); }
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--cible); padding: 0 var(--e3); border-radius: var(--rayon);
  text-decoration: none; font-family: var(--sans); font-weight: 700; font-size: var(--t-sm);
  border: 1px solid var(--trait-fort); color: var(--texte);
}
/* ⚠️ REGLE 2, mesuree, contre-intuitive : sur l'aplat --vif le texte est
   --sur-vif (noir), jamais --sur-aplat (blanc) — blanc ne fait que 3,95:1. */
.btn--primary { background: var(--vif); border-color: var(--vif); color: var(--sur-vif); }
.btn--primary:hover { filter: brightness(1.1); }
.btn--ghost:hover { border-color: var(--texte-faible); }

/* --- Le chiffre du heros : UN nombre enorme, pas une rangee de compteurs -
   ⚠️ Casse deliberee : l'ancien registre alignait cinq compteurs de meme
   poids visuel (30 / 200 / 182 / 60 / 13), tic releve dans les consignes.
   Un seul chiffre porte desormais le propos — 200, l'echelle de la carte —
   et les quatre autres passent en meta discrete, non encadree, plus petite
   qu'un simple libelle de colonne. Chasse fixe (--code) : c'est une DONNEE,
   jamais --titre — meme regle que documentee plus haut pour les tableaux. */
.chiffre-hero {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--e2) var(--e5);
  padding-block: var(--e5); border-top: 1px solid var(--trait); border-bottom: 1px solid var(--trait);
}
.chiffre-hero__nombre {
  font-family: var(--code); font-weight: 700; font-size: var(--t-geant);
  line-height: .82; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
  color: var(--texte); flex: none;
}
.chiffre-hero__texte { min-width: 14rem; }
.chiffre-hero__label {
  font-family: var(--sans); font-weight: 700; font-size: var(--t-lg);
  text-transform: uppercase; letter-spacing: .005em; margin: 0 0 var(--e2);
}
.chiffre-hero__meta {
  font-family: var(--code); font-size: var(--t-2xs); letter-spacing: .05em;
  text-transform: uppercase; color: var(--texte-discret); margin: 0; line-height: 1.7;
}

/* --- Bande de tatami : la vraie matiere, plus un motif dessine ----------
   ⚠️ Meme piege que le heros : la photo est un tatami bleu vif. Decorative
   ici (pas de la donnee), elle ne peut pas rester bleue sous la regle 1 —
   desaturee presque totalement, elle redevient une texture de fibre, pas
   une couleur. */
.tatami-rule {
  height: 4.5rem; background-image: url("img/tatami-800.webp");
  background-size: cover; background-position: center;
  /* Meme raison : l image est deja dans le bon registre, on ne la corrige
     plus apres coup. Voir le commentaire du heros. */
  border-block: 1px solid var(--trait); margin: 0;
}

/* --- Rupture de rythme : une photographie en pleine largeur, hors .wrap --
   La page d'accueil etait un mur de blocs de meme densite. Ce bloc casse
   le flux sans y ajouter de texte — l'image seule (deux pratiquants au
   sol) suffit a faire comprendre le sujet. Jamais de filtre : voir la
   regle du heros plus haut. Pas de legende : l'image sert d'ambiance, pas
   de preuve d'une technique nommee (voir consigne). */
.photo-large { margin: 0; border-block: 1px solid var(--trait); }
.photo-large img {
  width: 100%; height: clamp(16rem, 46vw, 32rem); object-fit: cover;
}

/* --- Bandeau photo avec citation courte -----------------------------------
   Troisieme traitement, distinct du duo texte/photo et de la rupture pure :
   une phrase courte posee sur l'image, jamais un paragraphe. Le voile est
   le meme principe que celui du heros (color-mix attache a --fond), assez
   fort pres du bas pour que le texte reste largement au-dessus du seuil —
   mesure sur la capture, pas au jugé (voir le rapport). */
.photo-bandeau { position: relative; margin: 0; overflow: hidden; border-block: 1px solid var(--trait); }
.photo-bandeau img {
  width: 100%; height: clamp(14rem, 38vw, 24rem); object-fit: cover; display: block;
}
/* ⚠️ Le bandeau est BAS (14–24rem), pas plein ecran comme le heros : les
   memes arrets de degrade en pourcentage y couvrent beaucoup moins de
   pixels reels. Mesure a 390px, le degrade du heros recopie tel quel ne
   suffisait pas (3,7:1, sous le seuil) — arrets remontes pour que le bas,
   la ou vit le texte, reste solide sur une part bien plus large du cadre. */
/* ⚠️ LE VOILE NE SERT QUE S'IL Y A UN TEXTE PAR-DESSUS. Il existe pour
   rendre lisible `.photo-bandeau__texte` ; applique a une bande sans texte,
   il ne protege rien et DELAVE la photo -- sur le fond clair depuis le
   2026-09-04, il transformait chaque photographie en fantome pale avec un
   bord sombre franc en haut. `:has()` le reserve donc aux bandes qui portent
   reellement un texte. */
.photo-bandeau:has(.photo-bandeau__texte)::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top,
    var(--fond) 42%,
    color-mix(in oklab, var(--fond) 88%, transparent) 66%,
    transparent 100%);
}
.photo-bandeau__texte {
  position: absolute; inset: auto 0 0 0; z-index: 1;
  padding: var(--e4) var(--e3); max-width: var(--lecture); margin: 0;
}
@media (min-width: 700px) { .photo-bandeau__texte { padding: var(--e4); } }
.photo-bandeau__texte p {
  font-family: var(--corps); font-style: italic; font-size: var(--t-lg);
  line-height: 1.4; color: var(--texte); margin: 0;
}

section { padding-block: var(--e6); }
section.alt { background: var(--carte); border-block: 1px solid var(--trait); }
.section-head { margin-bottom: var(--e4); max-width: var(--lecture); }
h2 {
  font-family: var(--titre); font-weight: 700; font-size: var(--t-xl);
  line-height: 1.05; letter-spacing: -.005em; text-transform: uppercase;
  text-wrap: balance; margin-bottom: var(--e2);
}
h3 { font-family: var(--titre); font-weight: 700; font-size: var(--t-lg); line-height: 1.15; }
.section-head p, .note { color: var(--texte-faible); }
.note { font-size: var(--t-sm); }
p + p { margin-top: var(--e3); }

/* --- Registre en tableau -------------------------------------------------
   ⚠️ Remplace les grilles de trois cartes egales (l'un des tics releves) :
   une liste de rangees separees par un filet, chacune ouverte par un index
   en chasse fixe. C'est la logique d'un registre, pas d'un mur de cartes
   identiques — et ca lit comme la marque d'un kimono qui numerote ses
   editions, pas comme un gabarit de dashboard. */
.rangee { border-top: 1px solid var(--trait); }
.rangee__item {
  display: grid; gap: var(--e1) var(--e4); padding-block: var(--e4);
  border-bottom: 1px solid var(--trait);
}
@media (min-width: 700px) {
  .rangee__item { grid-template-columns: 6rem 1fr; align-items: start; }
}
.rangee__num {
  font-family: var(--code); font-weight: 700; font-size: var(--t-2xl);
  line-height: 1; color: var(--texte-discret); font-variant-numeric: tabular-nums;
}
.rangee__num--mot {
  font-size: var(--t-2xs); letter-spacing: .1em; text-transform: uppercase;
  color: var(--vif); padding-top: .3rem;
}
.rangee__item h3 { margin-bottom: var(--e2); }
.rangee__item p { font-size: var(--t-sm); color: var(--texte-faible); }

/* --- Composition asymetrique : la preuve depuis la garde fermee ---------
   ⚠️ Casse deliberee : au lieu d'une grille de cartes egales, le premier
   bloc (11 chemins) prend toute la hauteur a gauche ; les trois autres
   s'empilent a droite, retrecissant avec leur propre nombre de chemins
   (4, puis 3, puis 1). La forme du bloc suit la donnee qu'il contient. */
.preuve-grid { display: grid; gap: var(--e3); }
.preuve-grid .card { display: flex; flex-direction: column; }
@media (min-width: 820px) {
  .preuve-grid {
    grid-template-columns: 1.5fr 1fr;
    grid-template-rows: repeat(3, auto);
  }
  .preuve-grid > :nth-child(1) { grid-column: 1; grid-row: 1 / 4; }
  .preuve-grid > :nth-child(2) { grid-column: 2; grid-row: 1; }
  .preuve-grid > :nth-child(3) { grid-column: 2; grid-row: 2; }
  .preuve-grid > :nth-child(4) { grid-column: 2; grid-row: 3; }
}

/* --- Cartes : des ecussons, pas des cartes arrondies ---------------------
   ⚠️ REGLE 3 : --rayon vaut 0 — cette regle cascade automatiquement ici. */
.card-grid { display: grid; gap: var(--e3); grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.card {
  background: var(--carte-haute); border: 1px solid var(--trait);
  border-radius: var(--rayon); padding: var(--e3);
}
section.alt .card { background: var(--fond); }
.card__index {
  font-family: var(--code); font-size: var(--t-2xs); color: var(--vif);
  letter-spacing: .1em; display: block; margin-bottom: var(--e2);
}
.card h3 { margin-bottom: var(--e2); }
.card p { font-size: var(--t-sm); color: var(--texte-faible); }

/* --- La progression par ceinture, illustree -----------------------------
   Le tableau reste en chasse fixe de bout en bout : c'est un registre, pas
   de la prose — meme les libelles de ceinture, pour l'effet de ledger. */
/* .duo-bloc/.duo-photo : meme grille photo+contenu, generalisee a toute
   paire photo/texte du site (comment-ca-marche, securite) — le nom
   "ceintures-" restait proprement lie a l'origine, mais la mise en page
   n'a rien de specifique aux ceintures. */
.ceintures-bloc, .duo-bloc { display: grid; gap: var(--e4); align-items: center; }
.ceintures-bloc > *, .duo-bloc > * { min-width: 0; }
@media (min-width: 900px) {
  .ceintures-bloc, .duo-bloc { grid-template-columns: 1fr 1.15fr; gap: var(--e5); }
}
.ceintures-photo, .duo-photo {
  border-radius: var(--rayon); overflow: hidden; border: 1px solid var(--trait);
}
.tableau-defile { overflow-x: auto; }
table.progression { width: 100%; border-collapse: collapse; font-family: var(--code); font-size: var(--t-sm); }
table.progression th, table.progression td {
  text-align: right; padding: var(--e2) var(--e1); border-bottom: 1px solid var(--trait);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
table.progression th:first-child, table.progression td:first-child { text-align: left; }
table.progression thead th {
  font-size: var(--t-2xs); letter-spacing: .08em;
  text-transform: uppercase; color: var(--texte-faible); font-weight: 500;
}
.ceint { display: inline-flex; align-items: center; gap: .55rem; }
.pastille { width: .85rem; height: .85rem; border-radius: var(--rayon); flex: none; }
.p-blanche { background: var(--c-blanche); }
.p-bleue { background: var(--c-bleue); }
.p-violette { background: var(--c-violette); }
.p-marron { background: var(--c-marron); }
.ceinture-noire, .p-noire { background: var(--c-noire); box-shadow: inset 0 0 0 1px var(--trait-fort); }
table.progression tr.plafond td { color: var(--texte-faible); }
table.progression td.zero { color: var(--or); font-weight: 700; }

/* --- Encarts ---------------------------------------------------------------
   ⚠️ Casse deliberee : plus d'encadre a filet colore SUR LA GAUCHE (l'un
   des tics releves). Le registre par defaut est un simple FILET HORIZONTAL
   au-dessus du texte — sans boite, sans fond. Une seule variante, reservee
   a l'affirmation la plus forte de la page d'accueil, passe en aplat rouge
   plein (regle 2 : texte --sur-vif). C'est l'exception qui justifie la
   regle, pas le traitement par defaut de tous les encarts. --------------- */
.callout {
  border: 0; border-top: 3px solid var(--vif); background: none;
  padding: var(--e3) 0 0; border-radius: 0; margin: 0;
}
.callout strong { color: var(--or); }

.callout--vif {
  border-top: 0; background: var(--vif); color: var(--sur-vif);
  padding: var(--e4);
}
.callout--vif strong { color: var(--sur-vif); text-decoration: underline; text-underline-offset: .15em; }

/* Le risque 3 « se signale par un retrait », pas par une couleur (voir
   globals.css) : un panneau recessé, pas un aplat criard — l'accent rouge
   est deja pris par le produit, on ne le lui emprunte pas pour le danger. */
.callout--risk {
  border-top: 0; background: var(--risque-3-fond);
  box-shadow: inset 0 0 0 1px var(--trait-fort); padding: var(--e4);
}
.callout--risk strong { color: var(--texte); }

/* --- Risque ------------------------------------------------------------- */
.risk-table { display: grid; gap: var(--e2); }
.risk-row {
  background: var(--carte-haute); border: 1px solid var(--trait);
  border-radius: var(--rayon); padding: var(--e3);
}
section.alt .risk-row { background: var(--fond); }
.risk-row--3 { background: var(--risque-3-fond); border-color: var(--trait-fort); }
.risk-row__head { display: flex; align-items: center; gap: var(--e2); margin-bottom: var(--e1); }
.risk-label {
  font-family: var(--code); font-size: var(--t-2xs); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
}
.risk-label--1 { color: var(--risque-1); }
.risk-label--2 { color: var(--risque-2); }
.risk-label--3 { color: var(--risque-3); }
.risk-row__meta { font-family: var(--sans); font-size: var(--t-sm); color: var(--texte-faible); }
.risk-dot { display: inline-block; width: .7rem; height: .7rem; border-radius: 50%; flex: none; }
.risk-dot--1 { background: var(--risque-1); }
.risk-dot--2 { background: var(--risque-2); }
.risk-dot--3 { background: var(--risque-3); }

/* --- Listes de specification ------------------------------------------- */
.spec-list { display: grid; gap: var(--e2); }
.spec-item {
  display: flex; gap: var(--e2); align-items: baseline;
  padding-bottom: var(--e2); border-bottom: 1px solid var(--trait); font-size: var(--t-sm);
}
.spec-item dt { font-family: var(--sans); font-weight: 700; color: var(--texte); }
.spec-item dt code {
  display: block; font-family: var(--code); font-weight: 400; font-size: var(--t-2xs);
  color: var(--texte-discret); text-transform: none; letter-spacing: 0; margin-top: .3rem;
}
.state-chips { display: flex; flex-wrap: wrap; gap: var(--e1); }
.state-chip {
  font-family: var(--code); font-size: var(--t-2xs); padding: .25rem .6rem;
  border-radius: var(--rayon); border: 1px solid var(--trait); color: var(--texte-faible);
}
.state-chip--on { color: var(--risque-1); border-color: var(--risque-1); }
.state-chip--risque3 { color: var(--risque-3); border-color: var(--risque-3); }

/* --- Liste de chemins (preuve du graphe, page d'accueil) ---------------- */
.chemin-liste { display: grid; gap: .55rem; margin-top: var(--e2); }
.chemin-liste li {
  display: flex; align-items: center; flex-wrap: wrap; gap: .55rem;
  font-family: var(--sans); font-size: var(--t-sm); color: var(--texte-faible);
}
.chemin-liste .pastille { flex: none; }

/* --- Etape suivante ----------------------------------------------------- */
.next-step { padding-block: var(--e6); }
.next-step__inner {
  display: grid; gap: var(--e3); justify-items: start;
  background: var(--carte-haute); border: 1px solid var(--trait);
  border-radius: var(--rayon); padding: var(--e4);
}
@media (min-width: 760px) {
  .next-step__inner { grid-template-columns: 1fr auto; align-items: center; }
}

/* --- Pied de page : cinq colonnes ----------------------------------------
   Marque, produit, apprendre, securite, maison — plus la ligne legale.
   Mentions legales, Vie privee et Cookies pointent desormais vers de vraies
   pages (mentions-legales.html, confidentialite.html, cookies.html).
   « Nous ecrire » reste seul en texte simple (.footer-inerte) : aucune page
   de contact n'existe encore, et un <a> ici menerait a un 404. */
.site-footer {
  border-top: 1px solid var(--trait); padding-block: var(--e6) var(--e4);
  color: var(--texte-faible); font-size: var(--t-sm);
}
.footer-grid {
  display: grid; gap: var(--e4) var(--e3);
  padding-bottom: var(--e4); border-bottom: 1px solid var(--trait);
}
@media (min-width: 640px) { .footer-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1180px) {
  .footer-grid { grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr; gap: var(--e4); }
}
.footer-marque { display: flex; align-items: center; gap: .55rem; text-decoration: none;
  margin-bottom: var(--e2); min-height: var(--cible); margin-inline-start: -.15rem; }
.footer-marque__mot {
  font-family: var(--titre); font-weight: 800; font-size: var(--t-md);
  text-transform: uppercase; letter-spacing: .01em; color: var(--texte);
}
.footer-marque__mot em { font-style: normal; }
.footer-col p.footer-baseline { max-width: 24rem; line-height: 1.6; font-size: var(--t-sm); }
.footer-col__titre {
  font-family: var(--code); font-size: var(--t-2xs); letter-spacing: .1em;
  text-transform: uppercase; color: var(--texte); margin: 0 0 var(--e2);
}
.footer-col ul { display: flex; flex-direction: column; gap: 0; margin: 0; padding: 0; list-style: none; }
.footer-col a, .footer-col .footer-inerte {
  display: inline-flex; align-items: center; min-height: var(--cible);
  font-family: var(--sans); font-size: var(--t-sm); text-decoration: none;
}
.footer-col a { color: var(--texte-faible); }
.footer-col a:hover { color: var(--texte); }
.footer-col .footer-inerte { color: var(--texte-discret); cursor: default; }
.footer-avenir {
  font-style: normal; font-family: var(--code); font-size: .68rem;
  letter-spacing: .05em; text-transform: uppercase; margin-left: .4rem;
  border: 1px solid var(--trait); border-radius: var(--rayon); padding: .1rem .4rem;
}
.footer-legal {
  display: flex; flex-wrap: wrap; gap: var(--e1) var(--e4);
  justify-content: space-between; padding-top: var(--e3);
  font-family: var(--code); font-size: var(--t-2xs); letter-spacing: .03em;
  color: var(--texte-discret);
}

/* ─────────────────────────────────────────────────────────────────────────
   TARIFS (site/tarifs.html). Trois formules. Les prix entre crochets sont
   des PROPOSITIONS, pas des prix fermes — voir le texte de la page. La
   mise en forme le rappelle visuellement (jeton --or, jamais une couleur
   qui donnerait un faux air d'officialite au chiffre).
   ⚠️ Casse deliberee : les trois formules ne sont plus de largeur egale —
   la formule recommandee est plus large, seule a recevoir l'aplat --vif
   (badge, regle 2 : texte --sur-vif dessus). Ce n'est plus un choix neutre
   presente trois fois a l'identique.
   ───────────────────────────────────────────────────────────────────────── */
.tarifs-intro { max-width: var(--lecture); margin: 0 auto var(--e5); text-align: center; }
.tarifs-intro .eyebrow { display: block; }
.plans { display: grid; gap: var(--e3); align-items: stretch; }
@media (min-width: 860px) { .plans { grid-template-columns: .92fr 1.16fr .92fr; } }
.plan {
  display: flex; flex-direction: column;
  background: var(--carte-haute); border: 1px solid var(--trait);
  border-radius: var(--rayon); padding: var(--e4); position: relative;
}
section.alt .plan { background: var(--fond); }
.plan--recommande { border-color: var(--vif); border-width: 2px; }
.plan__badge {
  position: absolute; top: -.75rem; left: var(--e3);
  background: var(--vif); color: var(--sur-vif);
  font-family: var(--code); font-size: var(--t-2xs); letter-spacing: .1em;
  text-transform: uppercase; padding: .25rem .6rem; border-radius: var(--rayon);
}
.plan__nom {
  font-family: var(--sans); font-weight: 700; font-size: var(--t-2xs); letter-spacing: .1em;
  text-transform: uppercase; color: var(--texte-faible); margin: 0 0 var(--e2);
}
/* ⚠️ var(--vif) sur --carte-haute en 13px/700 ne fait que 4,27:1 (mesure,
   sous le seuil 4,5:1) : l'accent reste porte par la bordure et le badge,
   pas par ce libelle. --texte (16,4:1) le distingue sans casser le seuil. */
.plan--recommande .plan__nom { color: var(--texte); }
.plan__prix {
  display: flex; align-items: baseline; gap: .4rem; flex-wrap: wrap;
  font-family: var(--titre); font-weight: 800; font-size: 2.75rem; line-height: 1;
}
.plan__prix .proposition { color: var(--or); }
.plan__periode { font-family: var(--code); font-size: var(--t-xs); color: var(--texte-faible); }
.plan__mention {
  font-family: var(--code); font-size: var(--t-2xs); letter-spacing: .06em;
  text-transform: uppercase; color: var(--or); margin-top: .5rem;
}
.plan__note { font-family: var(--sans); font-size: var(--t-xs); color: var(--texte-faible); margin: .4rem 0 var(--e3); }
.plan__features { display: flex; flex-direction: column; gap: .65rem; font-size: var(--t-sm);
  margin: 0 0 var(--e3); padding: 0; list-style: none; flex: 1; }
.plan__features li { padding-left: 1.05rem; position: relative; line-height: 1.45; }
.plan__features li::before { content: "—"; position: absolute; left: 0; color: var(--texte-discret); }
.plan__features li.plan__feature--absent { color: var(--texte-faible); }
.plan__features li.plan__feature--prevu { color: var(--texte-faible); }
.plan__feature--prevu .etiq-prevu {
  font-family: var(--code); font-size: .68rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--texte-discret); margin-left: .35rem;
}
.plan__cta { margin-top: auto; }

.tarifs-ancrage {
  display: grid; gap: var(--e3); margin-top: var(--e2);
}
@media (min-width: 640px) { .tarifs-ancrage { grid-template-columns: 1fr 1.25fr; } }
.tarifs-ancrage .card p { margin-top: .3rem; }

/* ⚠️ 44 px dans les DEUX sens, pied de page compris. Le lien « Tarifs » de la
   colonne « Le produit » ne faisait que 36 px de large : la hauteur passait,
   la largeur non, parce que le libelle est court. Mesure au navigateur sur le
   site publie — cela ne se voit pas en relisant le CSS, et les liens de pied
   de page sont ceux qu on oublie le plus souvent de verifier. */
.footer-col li a {
  display: inline-flex;
  align-items: center;
  min-height: var(--cible);
  min-width: var(--cible);
}

/* ─────────────────────────────────────────────────────────────────────────
   PAGES LÉGALES (mentions-legales.html, confidentialite.html, cookies.html).
   Pas de nouvelle couleur : tout est repris des jetons de tete de fichier.

   ⚠️ .a-completer signale une information legale qu'on n'a pas et qu'on
   n'invente pas (SIREN, adresse du siege...). Doit rester IMPOSSIBLE a
   confondre avec une vraie valeur : fond --risque-3-fond, filet --or,
   chasse fixe --code -- le meme traitement visuel qu'un avertissement de
   securite (--risque-3-fond existe deja pour ca), jamais du texte courant.
   ───────────────────────────────────────────────────────────────────────── */
.a-completer {
  display: inline-block; font-family: var(--code); font-size: var(--t-2xs);
  color: var(--or); background: var(--risque-3-fond);
  border: 1px solid var(--trait-fort); border-radius: var(--rayon);
  padding: .1rem .5rem; line-height: 1.5;
}

/* Table donnee / finalite / duree (confidentialite.html) : texte aligne a
   gauche partout, a l'inverse de table.progression (donnees numeriques,
   alignees a droite) -- ce n'est pas le meme genre de contenu, donc pas la
   meme classe. .tableau-defile (deja definie plus haut) porte le seul
   mecanisme de securite dont un tableau large a besoin sur telephone :
   overflow-x:auto sur son CONTENEUR, jamais sur le corps de page. */
table.donnees { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
table.donnees th, table.donnees td {
  text-align: left; vertical-align: top; padding: var(--e2) var(--e2) var(--e2) 0;
  border-bottom: 1px solid var(--trait);
}
table.donnees thead th {
  font-family: var(--code); font-size: var(--t-2xs); letter-spacing: .06em;
  text-transform: uppercase; color: var(--texte-faible); font-weight: 500;
  white-space: nowrap;
}
table.donnees td { font-family: var(--corps); color: var(--texte); }
table.donnees td.donnees__duree { font-family: var(--code); font-size: var(--t-xs); color: var(--texte-faible); white-space: nowrap; }
table.donnees .etiq-facultatif {
  display: inline-block; margin-left: .4rem; font-family: var(--code);
  font-size: .68rem; letter-spacing: .05em; text-transform: uppercase;
  color: var(--texte-discret); border: 1px solid var(--trait); border-radius: var(--rayon);
  padding: .05rem .35rem; vertical-align: middle;
}

/* Liste de droits (acces, rectification...) : meme registre "rangee" que le
   reste du site (voir .rangee plus haut), pas une nouvelle grille de cartes. */
.droits-liste { display: grid; gap: var(--e2); margin: 0; padding: 0; }
.droits-liste dt {
  font-family: var(--sans); font-weight: 700; font-size: var(--t-sm);
  color: var(--texte); margin-bottom: .2rem;
}
.droits-liste dd { margin: 0; font-size: var(--t-sm); color: var(--texte-faible); }
.droits-liste > div { padding-bottom: var(--e2); border-bottom: 1px solid var(--trait); }

/* ── Bouton d'inscription permanent en tete, sur mobile ───────────────────
   ⚠️ Il n'existe QUE sous 1100 px. Au-dessus, l'en-tete porte deja
   « Se connecter » et « Creer un compte » en permanence (.auth-row), et
   l'afficher deux fois donnerait deux boutons identiques cote a cote.
   Mesure du 2026-09-04 a 390 px : le premier ecran ne montrait que le
   mot « MENU » ; aucun appel a l'action de conversion n'etait atteignable
   sans un geste supplementaire. */
.entete-inscription {
  min-height: var(--cible);
  display: inline-flex;
  align-items: center;
  /* ⚠️ Pas de `margin-inline-start: auto` : .wrap est deja en
     space-between, et l'ajouter poussait l'ensemble hors de l'ecran. */
  white-space: nowrap;
}
@media (min-width: 1180px) {
  .entete-inscription { display: none; }
}
/* Sous 430 px, le libelle complet pousse le bouton « Menu » hors de l'ecran :
   on raccourcit le bouton, jamais la cible tactile. */
@media (max-width: 430px) {
  .entete-inscription { padding-inline: var(--e1, .5rem); font-size: var(--t-xs); }
}

/* ── Les captures de l'application ────────────────────────────────────────
   ⚠️ Ce sont de VRAIES captures de l'application en ligne, pas des
   maquettes. La page passe son temps a dire « verifiable » : y mettre un
   dessin de produit la contredirait.
   ⚠️ `width`/`height` sont poses sur chaque <img> et le rapport est
   conserve ici : sans cela, les cinq images de hauteurs differentes font
   sauter la mise en page pendant le chargement. */
.ecrans {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--e4);
  margin-top: var(--e5);
}
@media (min-width: 48rem) {
  .ecrans { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 72rem) {
  .ecrans { grid-template-columns: repeat(3, 1fr); }
}
.ecran { margin: 0; }
.ecran img {
  display: block;
  width: 100%;
  height: auto;
  /* Le haut de l'ecran suffit : au-dela on ne lit plus rien a cette taille,
     et une image de 2360px de haut ecraserait tout le reste de la section. */
  max-height: 30rem;
  object-fit: cover;
  object-position: top;
  border: 1px solid var(--trait-fort);
  border-radius: .6rem;
  background: var(--carte);
}
.ecran figcaption {
  margin-top: var(--e2);
  color: var(--texte-faible);
  font-size: var(--t-petit, .92rem);
  line-height: 1.5;
}
.ecran figcaption strong { color: var(--texte); font-weight: 700; }

/* ── Les morceaux de catalogue montres tels quels ─────────────────────────
   ⚠️ Le contenu de ces blocs est RECOPIE du catalogue reel. Si le catalogue
   change, ils changent avec lui, sinon ils deviennent la vitrine de ce qui
   n'existe plus. */
.preuves {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--e3);
  margin-top: var(--e5);
}
@media (min-width: 56rem) {
  .preuves { grid-template-columns: repeat(3, 1fr); align-items: start; }
}
.etiquette-preuve {
  margin: 0 0 var(--e2);
  color: var(--vif);
  font-family: var(--mono, monospace);
  font-size: var(--t-xs);
  letter-spacing: .06em;
  text-transform: uppercase;
}
.preuve-etapes {
  margin: var(--e2) 0;
  padding-inline-start: 1.2rem;
  line-height: 1.55;
}
.preuve-etapes li { margin-block: .5rem; }
.preuve-croquis {
  display: block;
  width: 100%;
  height: auto;
  margin-block: var(--e2);
  border-radius: .4rem;
}

/* La mention « compte requis » du mega-menu : presente mais discrete, elle
   previent sans decourager. Dite AVANT le clic, jamais decouverte apres. */
.mega__compte {
  margin-top: .6rem;
  color: var(--texte-faible);
  font-size: var(--t-xs);
}

/* ── La grille des trente schemas ─────────────────────────────────────────
   ⚠️ Ce sont NOS fichiers (public/croquis/, recopies au deploiement), pas des
   images d'ambiance : ils montrent le contenu du produit. Ils portent leur
   propre palette, figee dans le SVG : aucun filtre ni aucune couleur ne leur
   est applique ici, sous peine de les rendre illisibles dans un theme.
   ⚠️ `width`/`height` sur chaque <img> et rapport conserve : trente images
   qui arrivent une a une feraient sauter la mise en page tout du long. */
.croquis-grille {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--e3);
  margin-top: var(--e5);
}
@media (min-width: 40rem) { .croquis-grille { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 60rem) { .croquis-grille { grid-template-columns: repeat(5, 1fr); } }

.croquis-carte {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  /* 44 px de cible : chaque schema est un lien vers sa position. */
  min-height: var(--cible);
  padding: .5rem;
  border: 1px solid var(--trait);
  border-radius: .5rem;
  color: var(--texte);
  text-decoration: none;
  background: var(--carte);
}
.croquis-carte:hover { border-color: var(--vif); }
.croquis-carte img { display: block; width: 100%; height: auto; }
.croquis-carte span {
  font-family: var(--sans);
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--texte-faible);
  text-align: center;
}
.croquis-carte:hover span { color: var(--texte); }

/* Le schema mis en avant dans une section qui parle d'UNE position : le
   lecteur voit de quoi on lui parle avant de lire ce qui en part. */
.croquis-vedette {
  margin: var(--e4) auto 0;
  max-width: 26rem;
}
.croquis-vedette img { display: block; width: 100%; height: auto; }
.croquis-vedette figcaption {
  margin-top: var(--e2);
  color: var(--texte-faible);
  font-size: var(--t-xs);
  text-align: center;
}
/* Bande plus basse que .photo-bandeau : une matiere, pas une scene. */
.photo-bandeau--fine img { max-height: 16rem; object-fit: cover; }

/* « et N autres » a la fin d'une liste tronquee : le compte reste vrai, la
   liste ne fait plus dix lignes. Pas de pastille, ce n'est pas une technique. */
.chemin-reste {
  color: var(--texte-discret);
  font-style: italic;
  list-style: none;
  padding-left: 0;
}

/* ── L'annuaire des organisations ─────────────────────────────────────────
   ⚠️ AUCUN LOGO ici, ni ailleurs : ce sont des marques deposees, et les
   afficher sur un produit vendu laisserait croire a une affiliation qui
   n'existe pas. Des noms, un pays, des disciplines, un lien. */
.orgas {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--e3);
  margin-top: var(--e4);
}
@media (min-width: 40rem) { .orgas { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .orgas { grid-template-columns: repeat(3, 1fr); } }

/* ⚠️ L'icone est celle que le site publie POUR etre affichee a cote d'un
   lien vers lui. Ce n'est pas l'embleme de marque, qui n'est pas reproduit
   ici : voir l'en-tete de outils/generer_organisations.py.
   Fond blanc sous l'icone : beaucoup sont dessinees pour un fond clair et
   disparaitraient sur une carte teintee. */
.orga__icone {
  display: block; width: 32px; height: 32px;
  object-fit: contain;
  margin-bottom: .6rem;
  background: #fff;
  border-radius: .25rem;
  padding: 2px;
}
.orga__icone--vide {
  display: flex; align-items: center; justify-content: center;
  background: var(--fond); color: var(--texte-discret);
  font-family: var(--sans); font-size: var(--t-xs); font-weight: 700;
  border: 1px solid var(--trait);
}

.orga {
  padding: var(--e3);
  border: 1px solid var(--trait);
  border-radius: .5rem;
  background: var(--carte);
}
.orga h3 { margin: 0 0 .3rem; font-size: var(--t-moyen); }
/* 44 px de cible : chaque nom est un lien vers un site externe. */
.orga h3 a {
  display: inline-flex; align-items: center; min-height: 44px;
  color: var(--texte); text-decoration: none;
}
.orga h3 a:hover { color: var(--vif); text-decoration: underline; }
.orga__complet { margin: 0 0 .4rem; color: var(--texte-faible); font-size: var(--t-petit); }
.orga__meta {
  margin: 0; color: var(--texte-discret);
  font-family: var(--code); font-size: var(--t-xs); text-transform: uppercase;
  letter-spacing: .04em;
}

/* ── La bande d'organisations qui defile ──────────────────────────────────
   ⚠️ Ce n'est pas un mur de partenaires : la legende juste au-dessus le dit,
   et elle doit y rester. Ce sont les icones que chaque site publie pour etre
   affiche a cote d'un lien vers lui, pas leurs emblemes de marque.

   ⚠️ LA PISTE CONTIENT LA LISTE DEUX FOIS, et l'animation la deplace
   exactement de la moitie de sa largeur : c'est ce qui rend la boucle
   invisible. Changer l'un sans l'autre fait un saut a chaque tour. */
.bandeau-orgas {
  padding-block: var(--e3);
  border-block: 1px solid var(--trait);
  background: var(--carte);
  overflow: hidden;
}

.defile {
  display: block;
  overflow: hidden;
  /* La bande entiere est un lien vers l'annuaire : sans phrase, c'est le
     seul moyen qu'elle mene quelque part. */
  text-decoration: none;
}
.defile__piste {
  display: flex;
  align-items: center;
  gap: var(--e4);
  margin: 0;
  padding: 0;
  list-style: none;
  width: max-content;
  animation: defiler 46s linear infinite;
}
/* Le survol arrete la bande : on regarde une icone qui passe, on veut
   pouvoir la lire. Meme chose au clavier, via :focus-within. */
.defile:hover .defile__piste,
.defile:focus-within .defile__piste { animation-play-state: paused; }

.defile__piste img {
  display: block;
  width: 40px; height: 40px;
  object-fit: contain;
  background: #fff;
  border-radius: .3rem;
  padding: 3px;
  /* Grises au repos, en couleur au survol : une bande de trente logos
     multicolores tire l'oeil plus fort que le titre de la page. */
  filter: grayscale(1);
  opacity: .75;
  transition: filter .2s, opacity .2s;
}
.defile__piste img:hover { filter: none; opacity: 1; }

@keyframes defiler {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ⚠️ MOINS DE MOUVEMENT : une bande qui defile sans fin peut declencher un
   malaise chez les personnes sensibles au mouvement. Quand le systeme le
   demande, elle s'arrete et devient une simple rangee qu'on fait defiler
   soi-meme. */
@media (prefers-reduced-motion: reduce) {
  .defile { overflow-x: auto; }
  .defile__piste { animation: none; }
}
