/* =========================================================================
   LASCAUX INTERNATIONAL EXHIBITION — Base, layout et composants
   Typographie : Georgia uniquement (charte).
   Titres = CAPITALES BOLD · Sous-titres = CAPITALES REGULAR · Texte = regular.
   Ordre : reset → typo → layout → boutons → header → hero → composants → footer
   ========================================================================= */

/* =========================================================================
   1. RESET
   ========================================================================= */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
}

body {
  min-height: 100svh;
  background: var(--c-bg);
  color: var(--c-text);
  font-family: var(--f-body);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, picture, video, svg { display: block; max-width: 100%; }
img, video { height: auto; }

input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }

p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }
ul, ol { list-style: none; padding: 0; }
a { color: inherit; text-decoration: none; }

/* Les éléments SVG n'héritent pas toujours de la règle [hidden] du navigateur */
[hidden] { display: none !important; }

:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 3px;
  border-radius: 2px;
}

::selection { background: var(--lsx-1); color: var(--c-bone); }


/* =========================================================================
   2. TYPOGRAPHIE
   ========================================================================= */

/* Titres : capitales bold (charte) */
h1, h2 {
  font-family: var(--f-display);
  font-weight: 700;
  text-transform: uppercase;
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-title);
}

h1 { font-size: var(--t-h1); letter-spacing: var(--ls-hero); }
h2 { font-size: var(--t-h2); }

/* Sous-titres : capitales regular (charte) */
h3 {
  font-family: var(--f-display);
  font-size: var(--t-h3);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--ls-sub);
  line-height: var(--lh-snug);
}

h4 {
  font-family: var(--f-display);
  font-size: var(--t-h4);
  font-weight: 700;
  line-height: var(--lh-snug);
  letter-spacing: 0.01em;
}

p { max-width: var(--w-text); }

strong, b { font-weight: 700; color: var(--c-bone); }
em, i { font-style: italic; }

/* Sur-titre : petite capitale espacée, filet ocre */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  font-size: var(--t-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--c-accent);
  margin-bottom: var(--s-5);
}

/* Le filet est triplé, comme les traits parallèles du logotype : trois
   lignes fines qui descendent de l'orange vif au brun profond. Le filet
   inférieur est nettement plus sombre, ce qui creuse la profondeur du
   faisceau au lieu de donner trois traits d'égale valeur. */
.eyebrow::before {
  content: '';
  width: clamp(28px, 4.4vw, 54px);
  height: 8px;
  flex-shrink: 0;
  /* Trois traits déclarés séparément : chacun a sa longueur et son épaisseur.
     L'irrégularité est volontaire — un peigne parfaitement régulier aurait
     un air mécanique, là où le logotype garde la main du dessinateur. */
  background-image:
    linear-gradient(var(--lsx-1), var(--lsx-1)),   /* orange     — le plus long  */
    linear-gradient(var(--lsx-2), var(--lsx-2)),   /* ocre jaune — le plus épais */
    linear-gradient(var(--lsx-6), var(--lsx-6));   /* brun foncé — en retrait    */
  background-size:
    100% 1px,
     72% 1.5px,
     88% 1px;
  background-position:
    0 0,
    0 3.5px,
    0 7px;
  background-repeat: no-repeat;
}

/* Chapô */
/* Chapô : le paragraphe qui ouvre une page ou une section. Il passe à l'accent
   de lecture de la charte, ce qui le détache du corps de texte sans changer ni
   de corps ni de graisse — la couleur suffit à dire « ceci se lit d'abord ».

   « --c-accent » et non une couleur en dur : le rôle est redéfini par contexte,
   si bien qu'un chapô posé sur le papier clair d'une section ou du pied de page
   vire au brun ocre de lui-même. Contrastes mesurés : 6,7:1 sur le fond sombre,
   4,63:1 sur le papier — au-dessus du seuil dans les deux cas. */
.lead {
  font-size: var(--t-lead);
  font-weight: 700;
  line-height: 1.38;   /* resserré : le gras a besoin de moins d'air que le romain */
  color: var(--c-accent);
}

/* --- Trois filets décalés ------------------------------------------------
   Remplace le filet unique qui bordait les blocs à gauche. Le principe vient
   du logotype, dont chaque lettre est faite de traits parallèles déclinés
   dans les couleurs de la charte — on retrouve ici le même geste.

   Trois hauteurs et trois départs inégaux : l'irrégularité est voulue, un
   alignement parfait donnerait un peigne, non un tracé.

   Dessiné en dégradés plutôt qu'en pseudo-éléments : ::before et ::after ne
   font que deux, et ils sont souvent déjà pris ailleurs. Attention, tout
   bloc qui porte ces filets doit déclarer sa couleur de fond avec
   « background-color » et non le raccourci « background », qui les effacerait. */

.filets,
.pull,
.contact-card,
.stop {
  --filet-larg:  2px;
  --filet-ecart: 5px;
  --filet-1: var(--lsx-1);
  --filet-2: var(--lsx-3);
  --filet-3: var(--lsx-5);

  background-image:
    linear-gradient(var(--filet-1) 0 100%),
    linear-gradient(var(--filet-2) 0 100%),
    linear-gradient(var(--filet-3) 0 100%);
  background-repeat: no-repeat;
  background-size:
    var(--filet-larg) 66%,
    var(--filet-larg) 42%,
    var(--filet-larg) 25%;
  background-position:
    0 6%,
    var(--filet-ecart) 38%,
    calc(var(--filet-ecart) * 2) 17%;
}

/* Exergue en italique, usage ponctuel prévu par la charte */
/* La citation prend une couleur chaude de la charte plutôt que l'os du texte
   courant : elle cesse d'être un paragraphe en italique pour devenir une voix
   à part. L'ocre jaune, et non l'orange — celui-ci vient d'être donné aux
   liens, et deux orangés à quelques lignes l'un de l'autre se disputeraient
   l'attention. L'ocre tient 6,7 contre 1 sur l'encre ; sur le papier il
   tomberait à 1,9, où le brun ocre prend le relais à 4,6. Les trois filets qui
   la longent ne changent pas : ils portent déjà la palette. */
.pull {
  font-size: var(--t-lead);
  font-style: italic;
  line-height: 1.42;
  color: var(--citation);
  padding-left: var(--s-5);
  max-width: 52ch;
}

.section--papier .pull,
.article__feuille .pull { --citation: var(--lsx-5); }

/* Corps de texte long */
.prose > * + * { margin-top: 1.15em; }

/* --- Liens au fil du texte ---
   Jusqu'ici un lien dans un paragraphe ne se voyait pas : la règle générale
   met les liens en couleur héritée et sans soulignement, ce qui convient aux
   boutons et aux menus mais rendait invisible le lien vers la CNIL des pages
   légales. Un lien doit se signaler, et se signaler autrement que par la
   couleur seule — d'où le filet, qui ne dépend pas de la teinte.

   Le soulignement contourne les jambages au lieu de les barrer
   (text-decoration-skip-ink), et se pose un peu sous la ligne de base : dans
   une serif, un trait collé au texte mange les descendantes.

   Au survol, le filet prend la couleur pleine du lien et s'épaissit.

   Le gras s'ajoute à la couleur et au filet : trois signaux valent mieux
   qu'un, et dans un paragraphe long c'est lui qui accroche l'œil de loin. */
.prose a,
.article__corps a,
.page-hero__legende a,
.card__text a,
.equipe__credits a,
.equipe__actus a,
.equipe__toutes a {
  color: var(--lien);
  font-weight: 700;
  text-decoration: underline;
  text-decoration-color: var(--lien-filet);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-skip-ink: auto;
  transition: color var(--dur) var(--ease),
              text-decoration-color var(--dur) var(--ease),
              text-decoration-thickness var(--dur) var(--ease);
}

.prose a:hover,
.article__corps a:hover,
.page-hero__legende a:hover,
.card__text a:hover,
.equipe__credits a:hover,
.equipe__actus a:hover,
.equipe__toutes a:hover {
  text-decoration-color: var(--lien);
  text-decoration-thickness: 2px;
}

/* Sur le papier, l'orange de la charte tombe à 2,7 contre 1 : le brun ocre
   prend le relais, à 4,6. Les sections claires et la feuille des articles
   redéclarent donc la teinte, le reste de la règle ne bouge pas. */
.section--papier,
.article__feuille {
  --lien:       var(--lsx-5);
  --lien-filet: rgba(138, 81, 25, 0.55);
}

/* Un lien qui ouvre un autre site le dit. La flèche est collée au dernier mot
   par une espace insécable : elle ne doit jamais se retrouver seule en début
   de ligne. */
/* Un bouton porte déjà sa flèche : sans l'exception, « Le site de l'Atelier »
   en afficherait deux à la suite, → puis ↗. */
.prose a[target="_blank"]:not(.btn)::after,
.article__corps a[target="_blank"]:not(.btn)::after,
.card__text a[target="_blank"]:not(.btn)::after {
  content: '\00A0\2197';
  font-size: 0.82em;
  text-decoration: none;
  vertical-align: 0.06em;
}


.prose p { color: var(--c-bone-2); }

/* Un chapô reste un chapô, même posé dans un bloc de texte long : sans cette
   règle, « .prose p » l'emporterait par spécificité et lui reprendrait sa
   couleur. */
.prose p.lead { color: var(--c-accent); }
.prose h3 { margin-top: 2.2em; color: var(--c-bone); }
.prose h4 { margin-top: 2em; color: var(--c-accent); }
.prose ul { margin-top: 1.3em; }
.prose li { position: relative; padding-left: var(--s-5); color: var(--c-bone-2); }
.prose li + li { margin-top: var(--s-3); }
.prose li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.75em;
  width: 10px; height: 1px;
  background: var(--lsx-1);
}


/* =========================================================================
   3. LAYOUT & UTILITAIRES
   ========================================================================= */

.container {
  width: 100%;
  max-width: var(--w-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container--narrow { max-width: var(--w-content); }

.section { padding-block: var(--section-y); position: relative; }
.section--tight { padding-block: var(--section-y-s); }
.section--alt { background: var(--c-bg-alt); }
.section--ruled { border-top: 1px solid var(--c-border-soft); }

.stack > * + * { margin-top: var(--s-5); }
.stack-lg > * + * { margin-top: var(--s-7); }

.section-head { display: grid; gap: var(--s-6) var(--s-8); margin-bottom: var(--s-8); }

/* La suite du texte de « La visite », sous le titre. Corps courant : elle
   raconte le détail, quand le chapô ocre en regard donne l'intention. */
.visite__suite {
  margin-top: var(--s-5);
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--c-text-muted);
}

@media (min-width: 900px) {
  .section-head--split {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: end;
  }

  /* Le chapô de droite occupait toute sa colonne : sur un texte long, cela
     donnait un pavé large et bas, sans rapport avec la colonne de titre en
     regard. On resserre sa mesure — il gagne en hauteur ce qu'il perd en
     largeur, et les deux colonnes se répondent au lieu de se déséquilibrer.
     Le bloc reste calé sur la marge de droite : resserré ET flottant au
     milieu de sa colonne, il n'aurait plus été tenu par rien. Un chapô court
     ne s'aperçoit de rien. */
  .section-head--split .lead {
    max-width: 26ch;
    margin-left: auto;
  }

  /* Un texte courant sous le titre, dans la colonne de gauche : il prolonge le
     titre au lieu de lui répondre, et garde donc sa mesure — celle de la
     colonne — là où le chapô de droite se resserre. */
  /* Troisième enfant de la grille : elle tombe d'elle-même sous le titre, à
     gauche. En une colonne, elle vient après le chapô ocre — l'intention
     d'abord, le détail ensuite. */
  .visite__suite { grid-column: 1; max-width: 46ch; margin-top: 0; }
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  top: -100%; left: var(--s-4);
  z-index: var(--z-top);
  padding: var(--s-3) var(--s-5);
  background: var(--lsx-1);
  color: var(--c-bone);
  font-weight: 700;
  border-radius: var(--radius-s);
}

.skip-link:focus { top: var(--s-4); }


/* --- Bandeau d'article en brouillon ---
   Posé tout en haut, avant l'en-tête, sur toute la largeur : il doit se voir
   avant la page, et ne ressembler à rien d'autre sur le site. Le rouge brique
   de la charte, jamais employé en aplat ailleurs, dit l'avertissement sans
   sortir de la palette. Il défile avec la page : ce n'est pas une alarme à
   garder sous les yeux, c'est un état à connaître en arrivant. */
.bandeau-brouillon {
  position: relative;
  z-index: var(--z-top);
  margin: 0;
  padding: var(--s-3) var(--gutter);
  background: var(--lsx-3);
  color: var(--c-bone);
  font-size: var(--t-micro);
  line-height: 1.45;
  text-align: center;
  text-wrap: pretty;
}

.bandeau-brouillon strong {
  color: inherit;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin-right: var(--s-2);
}


/* =========================================================================
   4. BOUTONS & LIENS
   ========================================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  min-height: 52px;
  padding: var(--s-3) var(--s-6);
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border-radius: var(--radius-s);
  border: 1px solid transparent;
  transition: background var(--dur) var(--ease),
              color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}

.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

/* Aplat de couleur charte avec typo en réserve (jamais de typo noire dessus) */
.btn--primary { background: var(--lsx-1); color: var(--c-bone); }
.btn--primary:hover { background: var(--lsx-3); }

/* Le contour se remplit au survol, comme le bouton de sortie : les trois
   boutons du site répondent alors du même geste. Chacun avance d'un cran dans
   la palette — le contour prend l'orange, l'aplat orange passe au rouge. */
.btn--ghost { border-color: var(--c-border); color: var(--c-bone); }

.btn--ghost:hover,
.btn--ghost:focus-visible {
  background: var(--lsx-1);
  border-color: var(--lsx-1);
  color: var(--c-bone);
}

/* Bouton de sortie : le passage d'une page à l'autre.
   Le lien fléché employé jusqu'ici se confondait avec le texte courant et
   n'appelait pas le clic. Celui-ci porte le cadre à l'orange dès le repos —
   on le voit sans le survoler — et se remplit au survol, comme le bouton
   principal de l'accueil. Il reste en dessous de lui : un cadre n'est pas un
   aplat, la hiérarchie du hero est préservée. */
.btn--sortie {
  border-color: var(--lsx-1);
  color: var(--c-bone);
}

.btn--sortie:hover,
.btn--sortie:focus-visible {
  background: var(--lsx-1);
  color: var(--c-bone);
}

.btn--sortie .arw { transition: transform var(--dur) var(--ease); }
.btn--sortie:hover .arw,
.btn--sortie:focus-visible .arw { transform: translateX(5px); }

/* Sur le papier clair, l'orange plein serait criard : on garde le cadre et
   c'est le texte qui vire. */
.section--papier .btn--sortie,
.footer .btn--sortie { border-color: var(--lsx-5); color: var(--c-text); }

.section--papier .btn--sortie:hover,
.footer .btn--sortie:hover { background: var(--lsx-5); color: #FFFCF5; }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-accent);
  padding-block: var(--s-2);
}

.link-arrow .arw { transition: transform var(--dur) var(--ease); }
.link-arrow:hover .arw { transform: translateX(6px); }


/* =========================================================================
   5. HEADER / NAVIGATION
   ========================================================================= */

.header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-header);
  height: var(--header-h);
  display: flex;
  align-items: center;
  border-bottom: 1px solid transparent;
  transition: background var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              backdrop-filter var(--dur) var(--ease);
}

.header.is-solid,
.header.is-opaque {
  background: rgba(23, 19, 15, 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--c-border-soft);
}

.header__inner {
  width: 100%;
  max-width: var(--w-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
}

/* --- Logo ---
   Fichier officiel : assets/img/logo-lascaux.svg (recadré depuis LSX 01.svg,
   tracé inchangé). Charte : toujours en couleur, avec la baseline bilingue,
   jamais monochrome, jamais sous 200 px de long.
   La marge droite matérialise la zone de protection (49 % de la hauteur). */

.logo {
  display: block;
  flex-shrink: 0;
  line-height: 0;
  margin-right: calc(var(--logo-w) / 3.666 * 0.49);
}

.logo img {
  width: var(--logo-w);
  height: auto;
}

/* Sur petit écran, le logo garde sa longueur minimale de 200 px : la charte
   ne permet ni de le réduire davantage, ni de retirer sa baseline. C'est donc
   le sélecteur de langue qui quitte l'en-tête — il reste accessible en bas du
   menu plein écran — pour laisser la place au bouton de menu. */
@media (max-width: 860px) {
  .header__actions .lang-switch { display: none; }
}

@media (max-width: 460px) {
  .logo { margin-right: var(--s-3); }
}

/* --- Navigation desktop --- */

.nav { display: none; }

/* Le menu complet n'apparaît qu'à partir de 1280 px : en dessous, les cinq
   entrées, le bouton de contact et le sélecteur de langue ne tiennent pas à
   côté du logo — mesuré, ils débordaient de 119 px à 1080 px. Le bouton de
   menu prend le relais jusque-là. */
@media (min-width: 1280px) {
  .nav { display: flex; align-items: center; gap: clamp(var(--s-4), 1.9vw, var(--s-6)); }
}

.nav__link {
  position: relative;
  font-size: var(--t-micro);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  padding-block: var(--s-3);
  color: var(--c-bone-3);
  white-space: nowrap;
  transition: color var(--dur) var(--ease);
}

.nav__link::after {
  content: '';
  position: absolute;
  left: 0; bottom: 2px;
  width: 100%; height: 1px;
  background: var(--lsx-1);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}

.nav__link:hover { color: var(--c-bone); }
.nav__link:hover::after { transform: scaleX(1); }

.nav__link[aria-current='page'] { color: var(--c-bone); }
.nav__link[aria-current='page']::after { transform: scaleX(1); }

/* --- Actions : langue + burger --- */

.header__actions { display: flex; align-items: center; gap: var(--s-3); }

.lang-switch {
  display: flex;
  align-items: center;
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.lang-switch a, .lang-switch span {
  padding: var(--s-2) var(--s-3);
  transition: color var(--dur) var(--ease);
}

.lang-switch [aria-current='true'] { color: var(--c-accent); font-weight: 700; }
.lang-switch a:not([aria-current='true']) { color: var(--c-bone-3); }
.lang-switch a:hover { color: var(--c-bone); }
.lang-switch .sep { color: var(--c-border); padding: 0; }

/* --- Rond de contact ---
   Raccourci permanent vers le formulaire, dans le même langage que le bouton
   d'ambiance : un cercle, une bordure fine, l'ocre au survol. Il reste visible
   sur mobile, là où le sélecteur de langue s'efface. */

.action-round {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  flex-shrink: 0;
  border: 1px solid transparent;
  border-radius: 50%;
  color: var(--c-bone);
  /* Aplat orange vers rouge brique, deux des sept couleurs officielles,
     avec l'icône en réserve — la charte proscrit le noir sur aplat. */
  background: linear-gradient(135deg, var(--lsx-1) 0%, var(--lsx-3) 100%);
  transition: background var(--dur) var(--ease),
              transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}

.action-round:hover {
  background: linear-gradient(135deg, var(--lsx-3) 0%, var(--lsx-4) 100%);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px -6px rgba(212, 97, 15, 0.6);
}

.action-round:active { transform: translateY(0); }

/* Page courante : l'aplat s'inverse, le rond marque sa position */
.action-round[aria-current='page'] {
  background: linear-gradient(135deg, var(--lsx-4) 0%, var(--lsx-1) 100%);
}

.action-round svg { fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }

/* --- Mention au survol du rond de contact ---
   Le libellé apparaît à gauche du rond, en italique, et glisse depuis la
   droite. Il est décoratif : le nom accessible du lien reste porté par
   aria-label, que les lecteurs d'écran annoncent de toute façon. */

.action-round__mention {
  position: absolute;
  right: calc(100% + var(--s-3));
  top: 50%;
  transform: translateY(-50%) translateX(6px);
  white-space: nowrap;
  font-style: italic;
  font-size: var(--t-small);
  color: var(--c-accent);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease-out);
}

.action-round:hover .action-round__mention,
.action-round:focus-visible .action-round__mention {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

/* Sous 860 px le sélecteur de langue s'efface déjà : la place manque */
@media (max-width: 860px) {
  .action-round__mention { display: none; }
}

.burger {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  margin-right: -10px;
  flex-shrink: 0;
}

@media (min-width: 1280px) { .burger { display: none; } }

.burger__box { position: relative; width: 24px; height: 14px; }

.burger__box span {
  position: absolute;
  left: 0;
  width: 100%; height: 1.5px;
  background: var(--c-bone);
  transition: transform var(--dur) var(--ease), opacity 0.2s var(--ease);
}

.burger__box span:nth-child(1) { top: 0; }
.burger__box span:nth-child(2) { top: 50%; transform: translateY(-50%); }
.burger__box span:nth-child(3) { bottom: 0; }

.burger[aria-expanded='true'] .burger__box span:nth-child(1) { transform: translateY(6.25px) rotate(45deg); }
.burger[aria-expanded='true'] .burger__box span:nth-child(2) { opacity: 0; }
.burger[aria-expanded='true'] .burger__box span:nth-child(3) { transform: translateY(-6.25px) rotate(-45deg); }

/* --- Menu plein écran --- */

.menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  background: var(--c-ink);
  padding: calc(var(--header-h) + var(--s-7)) var(--gutter) var(--s-7);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity var(--dur) var(--ease),
              transform var(--dur) var(--ease),
              visibility var(--dur);
}

.menu.is-open { opacity: 1; visibility: visible; transform: translateY(0); }

/* --- Fonds de matière du menu -------------------------------------------
   Une paroi par entrée, révélée en fondu au survol. Les calques sont créés
   par site.js à la première ouverture ; les chemins des images restent ici,
   résolus depuis cette feuille de style.

   Chaque matière a été choisie pour ce qu'elle dit de la page : la lampe
   dans la grotte pour l'histoire de Lascaux, la paroi pour l'exposition,
   les chevaux qui courent pour la tournée. */

.menu { isolation: isolate; }
.menu > nav,
.menu > .menu__foot { position: relative; z-index: 1; }

.menu__fonds {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.menu__fond {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: 0;
  /* Sur ce noir, « screen » ne laisse passer que les parties claires de la
     paroi : la matière apparaît sans éclaircir le fond en bloc. */
  mix-blend-mode: screen;
  /* Un fondu long : le menu doit respirer, non clignoter au passage de la
     souris d'une entrée à l'autre. */
  transition: opacity var(--menu-fond-duree) var(--ease-out),
              transform var(--menu-fond-duree) var(--ease-out);
  /* Très légère dérive : la matière semble se poser plutôt qu'apparaître. */
  transform: scale(1.06);
  /* Estompé vers le bas, pour que le pied de menu reste lisible. */
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 52%, transparent 92%);
  mask-image: linear-gradient(180deg, #000 0%, #000 52%, transparent 92%);
}

.menu[data-fond='1'] .menu__fond[data-fond='1'],
.menu[data-fond='2'] .menu__fond[data-fond='2'],
.menu[data-fond='3'] .menu__fond[data-fond='3'],
.menu[data-fond='4'] .menu__fond[data-fond='4'],
.menu[data-fond='5'] .menu__fond[data-fond='5'] {
  opacity: calc(var(--menu-fond-opacite) * var(--menu-fond-facteur, 1));
  transform: scale(1);
}

/* Chaque matière porte son propre facteur, faute de quoi une opacité unique
   donnerait cinq présences très différentes : posées en « screen » sur du
   noir, ce sont les parties claires qui ressortent, et elles varient du
   simple au triple d'une paroi à l'autre. Facteurs calculés sur le 90e
   centile de luminance de chaque image, la matière 26 servant de référence. */

/* À propos — les cerfs affrontés, figures pariétales.
   La scène à la lampe employée d'abord ne tenait pas : son sujet est concentré
   sur quelques pixels clairs, et à cette opacité il ne restait qu'une tache
   sans lecture possible. Les bois des cerfs, eux, sont des formes franches qui
   se lisent en filigrane. Comme les chevaux, le dessin a été inversé et viré
   à l'ocre — sombre sur papier clair, il aurait disparu en « screen ». */
.menu__fond[data-fond='1'] {
  background-image: url('../img/matieres/opt/cerfs.jpg');
  --menu-fond-facteur: 1.99;
}
.menu__fond[data-fond='2'] {                     /* L'exposition — la paroi */
  background-image: url('../img/matieres/opt/2.jpg');
  --menu-fond-facteur: 2.12;
}
.menu__fond[data-fond='3'] {                     /* Tournée — les chevaux qui courent */
  background-image: url('../img/matieres/opt/chevaux.jpg');
  --menu-fond-facteur: 0.8;
}
.menu__fond[data-fond='4'] {                     /* Actualités — la paroi ocre */
  background-image: url('../img/matieres/opt/26.jpg');
  --menu-fond-facteur: 1;
}
.menu__fond[data-fond='5'] {                     /* Contact — la paroi sombre */
  background-image: url('../img/matieres/opt/1.jpg');
  --menu-fond-facteur: 2.82;
}

@media (prefers-reduced-motion: reduce) {
  .menu__fond { transition: opacity var(--menu-fond-duree) linear; transform: none; }
  .menu[data-fond] .menu__fond { transform: none; }
}

@media (min-width: 1280px) { .menu { display: none; } }

.menu__list > li + li { margin-top: var(--s-4); }

.menu__link {
  display: block;
  font-family: var(--f-display);
  font-size: clamp(1.65rem, 7.5vw, 2.75rem);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.015em;
  line-height: 1.15;
  padding-block: var(--s-2);
  color: var(--c-bone);
  transition: color var(--dur) var(--ease);
}

.menu__link:hover,
.menu__link[aria-current='page'] { color: var(--c-accent); }

.menu__foot {
  margin-top: var(--s-8);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-border-soft);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  font-size: var(--t-small);
  color: var(--c-text-muted);
}

body.is-locked { overflow: hidden; }


/* =========================================================================
   6. HERO — vidéo plein écran
   ========================================================================= */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  isolation: isolate;
  overflow: hidden;
  background: var(--c-ink-deep);
}

.hero__media { position: absolute; inset: 0; z-index: -2; background: var(--c-ink-deep); }

.hero__media video,
.hero__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Le fond noir des conteneurs sert d'écran pendant le fondu : l'opacité de
   la vidéo est pilotée par site.js, qui lit --video-fade.
   L'agrandissement, lui, sort du cadre le logo incrusté en haut à droite. */
.hero__media video,
.page-hero__media video,
.media-band__media video {
  transition: opacity var(--video-fade) ease;
  transform: scale(var(--video-zoom)) translateY(var(--video-shift));
  transform-origin: center;
}

/* --- Pages à titres resserrés ---
   L'accueil et la page Exposition enchaînent de grands titres posés sur des
   images : à 83 px pour le premier et 52 px pour les suivants, ils écrasaient
   les photographies et repoussaient le texte hors de l'écran. Ils sont
   ramenés d'un quart environ sur ces deux pages seulement ; les autres, où le
   titre est seul en tête, gardent l'échelle générale.
   Mesuré à 1440 px : 83 → 64 px, 52 → 40 px. */
.titres-reduits {
  --t-h1: clamp(1.7rem, 3.6vw, 3.2rem);
  --t-h2: clamp(1.45rem, 2.9vw, 2.5rem);
}

/* --- Section posée sur une photographie ---
   Le fond est choisi au hasard parmi les affiches du montage, à chaque
   affichage de la page : le chantier passe derrière le texte qui le raconte.
   Deux calques sous le contenu : la photographie, éclaircie comme les autres
   médias, et par-dessus un voile vertical assez dense pour que le texte se
   lise sans effort — ici il est centré et étroit, un dégradé latéral ne
   servirait à rien. */
.section--fond-photo {
  position: relative;
  isolation: isolate;
}

.section--fond-photo::before,
.section--fond-photo::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

/* Le défilé occupe le calque du fond ; les voiles restent au-dessus de lui. */
.section--fond-photo .fond-defile { z-index: -2; }

.section--fond-photo::before {
  background: var(--fond-photo) center / cover no-repeat;
  filter: var(--video-lumiere);
}

/* --- Fonds qui se succèdent en fondu ---
   Les six affiches du montage empilées, chacune paraissant six secondes,
   séparées par un fondu d'une seconde et demie : une boucle de trente-six
   secondes. Le fondu est en CSS seul, comme celui du bandeau de l'accueil,
   et l'ordre des images est tiré au sort à chaque affichage de la page.
   Sans JavaScript, sans minuterie : rien à interrompre au défilement. */
.fond-defile {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

.fond-defile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  filter: var(--video-lumiere);
  animation: fond-fondu var(--fond-boucle, 36s) var(--ease) infinite;
}

.fond-defile img:nth-child(1) { opacity: 1; animation-delay: -1.5s; }
.fond-defile img:nth-child(2) { animation-delay:  4.5s; }
.fond-defile img:nth-child(3) { animation-delay: 10.5s; }
.fond-defile img:nth-child(4) { animation-delay: 16.5s; }
.fond-defile img:nth-child(5) { animation-delay: 22.5s; }
.fond-defile img:nth-child(6) { animation-delay: 28.5s; }

@keyframes fond-fondu {
  0%     { opacity: 0; }
  4.2%   { opacity: 1; }
  16.7%  { opacity: 1; }
  20.9%  { opacity: 0; }
  100%   { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .fond-defile img { animation: none; }
  .fond-defile img:nth-child(1) { opacity: 1; }
  .fond-defile img + img { opacity: 0; }
}

/* Deux voiles superposés, comme sur les bandeaux : le halo horizontal tient
   la lisibilité à gauche, où le texte se pose, et laisse la photographie se
   montrer à droite ; le voile vertical, léger au centre et dense aux deux
   bords, fond la section dans la page sans laisser d'arête. */
.section--fond-photo::after {
  background: var(--halo-texte),
              linear-gradient(180deg,
                rgba(14, 11, 8, 0.92) 0%,
                rgba(14, 11, 8, 0.22) 38%,
                rgba(14, 11, 8, 0.22) 62%,
                rgba(14, 11, 8, 0.92) 100%);
}

/* Le texte se range à gauche, dans la part sombre du halo : centré, sa moitié
   droite passerait sur la photographie en pleine lumière. */
.section--fond-photo .container { max-width: var(--w-max); }
.section--fond-photo .prose { max-width: 52ch; }

/* --- Lumière des médias ---
   Les plans sont sombres à la prise de vue, et le voile les assombrit encore.
   On éclaircit donc l'image elle-même plutôt que de lever le voile, et le
   halo de lisibilité (plus bas) rend au texte le contraste qu'il y perd. */
.hero__media video,
.hero__media img,
.page-hero__media video,
.page-hero__media img,
.media-band__media video,
.media-band__media img { filter: var(--video-lumiere); }


/* --- Ken Burns : dérive lente sur image fixe ---------------------------
   Employé là où une vidéo ralentie saccaderait. Les plans sont à 30 i/s :
   à 0,3× il ne resterait que 9 images par seconde, très en dessous du seuil
   de fluidité. Une image fixe animée par transform reste fluide, pèse
   quinze fois moins et n'exige aucun décodage vidéo. */

.kenburns {
  animation: kenburns var(--kb-duree) ease-in-out infinite alternate;
  transform-origin: 55% 45%;
  will-change: transform;
}

@keyframes kenburns {
  from { transform: scale(var(--kb-depart)) translate(0, 0); }
  to   { transform: scale(var(--kb-arrivee)) translate(var(--kb-dx, -2.5%), var(--kb-dy, -1.5%)); }
}

/* Variante légère, pour les photos des bandeaux de page : la photo
   respire, sans attirer l'œil loin du titre. Le cycle démarre déjà engagé
   (délai négatif) : sans cela, la courbe ease-in-out part au ralenti et
   rien ne bouge de façon visible pendant les dix premières secondes —
   le temps qu'un visiteur passe souvent sur le bandeau. */
.kenburns--leger {
  --kb-duree:   30s;
  --kb-depart:  1.03;
  --kb-arrivee: 1.10;
  --kb-dx: -1.5%;
  --kb-dy: -1%;
  animation-delay: -9s;
}

@media (prefers-reduced-motion: reduce) {
  .kenburns { animation: none; transform: scale(var(--kb-depart)); }
}

.hero__media::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Deux fonds superposés : le halo horizontal par-dessus le voile
     vertical. Le halo tient la lisibilité à gauche, où le texte se pose ;
     le voile tient le haut et le bas, où le hero rejoint l'en-tête et la
     page. */
  background: var(--halo-texte), var(--veil-hero);
}

.hero__inner {
  position: relative;
  width: 100%;
  max-width: var(--w-max);
  margin-inline: auto;
  padding: calc(var(--header-h) + var(--s-8)) var(--gutter) clamp(var(--s-7), 7vh, var(--s-9));
}

.hero__title {
  font-size: var(--t-hero);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-hero);
  max-width: 20ch;
  text-wrap: balance;
}

.hero__tagline {
  font-size: var(--t-lead);
  font-style: italic;
  color: var(--c-bone-2);
  max-width: 48ch;
  margin-top: var(--s-5);
}

/* Le paragraphe que la cliente ajoute sous la signature : il raconte, là où
   la signature annonce. Donc du romain contre l'italique, un corps courant
   contre le corps de chapô, et une mesure un peu plus large — sans quoi les
   deux blocs se disputeraient le même rang.

   Il s'affiche partout. Une première version le masquait sous 700 px de
   hauteur, pour garder le héros d'un seul tenant — mais beaucoup d'écrans
   portables sont dans ce cas, et le texte disparaissait alors pour une part
   des visiteurs. Un contenu demandé ne s'escamote pas : le héros grandit
   au-delà de la fenêtre, et le décompte passe sous la ligne de flottaison,
   ce qui est son sort normal quand l'écran est bas. */
.hero__texte {
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--c-bone-2);
  max-width: 62ch;
  margin-top: var(--s-4);
}

.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-4); margin-top: var(--s-7); }

.hero__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-5) var(--s-8);
  margin-top: var(--s-8);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-border);
}

/* --- Surface du bouton de son ---
   Le bouton est posé sur une surface flottante : détachée du bord, sans
   contour, à peine teintée, avec un flou d'arrière-plan. Elle n'est pas un
   ornement — c'est elle qui tient le contraste du picto, aussi bien sur une
   paroi sombre que sur le papier d'une section claire.

   Sur la landing, le bouton est employé seul, sans cette surface : il y garde
   son propre fond (voir site-vitrine/assets/css/landing.css).
   → WordPress : un seul bloc, à sortir dans le gabarit de l'accueil. */

.son-surface {
  position: absolute;
  right: var(--gutter);
  top: calc(var(--header-h) + var(--s-4));
  z-index: var(--z-flottant);
  display: flex;
  flex-direction: column;        /* le mot se déplie sous le picto */
  align-items: center;
  padding: 14px 10px;            /* plus haute que large, même au repos */
  border-radius: 999px;
  color: var(--c-bone);
  /* Pas de flou d'arrière-plan : la surface se pose sur la page, elle ne la
     masque pas. Ce qui passe dessous — un mot du titre, une figure de la
     paroi — doit rester lisible à travers. Seul un voile très léger et une
     ombre portée la détachent. */
  background: rgb(14 11 8 / var(--son-voile));
  box-shadow: 0 8px 28px rgb(0 0 0 / 0.22);
  transition: background var(--dur) var(--ease), padding var(--dur) var(--ease),
              opacity 0.5s var(--ease), visibility 0s;
}

/* Le déploiement suit la souris et se referme dès qu'elle s'éloigne. Au
   clavier seulement — :focus-visible, et non :focus-within —, sans quoi le mot
   resterait déplié après un clic, le bouton gardant le focus une fois la
   souris partie. */
.son-surface:hover,
.son-surface:has(.video-toggle:focus-visible) {
  background: rgb(14 11 8 / calc(var(--son-voile) + 0.18));
  padding-bottom: 12px;
}

/* Le mot ne se déplie qu'au survol ou au clavier : au repos, le picto suffit,
   et la surface reste discrète. Il est masqué aux lecteurs d'écran, qui lisent
   déjà le libellé du bouton — sans quoi le son serait annoncé deux fois.
   Il est écrit plus petit que --t-micro : ce n'est pas une étiquette à lire,
   seulement un mot chuchoté à côté du picto, que l'interlettrage suffit à
   rendre lisible. */
.son-surface__mot {
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  max-height: 0;
  margin-top: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height var(--dur) var(--ease), margin-top var(--dur) var(--ease),
              opacity var(--dur) var(--ease);
}

.son-surface:hover .son-surface__mot,
.son-surface:has(.video-toggle:focus-visible) .son-surface__mot {
  max-height: 1.4em;
  margin-top: 6px;
  opacity: 1;
}

/* Dans la surface, le bouton abandonne son propre fond : deux épaisseurs de
   voile l'une sur l'autre alourdiraient l'ensemble. */
.son-surface .video-toggle {
  position: relative;
  right: auto;
  top: auto;
  background: none;
  border-color: transparent;
  backdrop-filter: none;
}

.son-surface .video-toggle:hover { background: none; color: var(--lsx-1); }

/* --- Bouton d'ambiance sonore ---
   Au repos, un simple cercle. Actif, il s'entoure d'un anneau qui reprend la
   répétition colorée des traits du logotype — les sept teintes de la charte
   défilent en boucle — et d'ondes qui se propagent au rythme du son. */

.video-toggle {
  position: absolute;
  right: var(--gutter);
  top: calc(var(--header-h) + var(--s-4));
  z-index: 2;
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border: 1px solid var(--c-border);
  border-radius: 50%;
  color: var(--c-bone);
  background: rgba(14, 11, 8, 0.45);
  backdrop-filter: blur(6px);
  isolation: isolate;
  transition: border-color var(--dur) var(--ease),
              background var(--dur) var(--ease),
              color var(--dur) var(--ease);
}

.video-toggle svg { position: relative; z-index: 2; }

.video-toggle:hover { border-color: var(--lsx-1); background: rgba(14, 11, 8, 0.75); }

/* L'anneau multicolore : les sept couleurs de la charte, parcourues deux fois,
   masquées en couronne fine et mises en rotation lente. */
.video-toggle::before {
  content: '';
  position: absolute;
  inset: -4px;
  z-index: 1;
  border-radius: 50%;
  background: conic-gradient(from 0deg,
    var(--lsx-1), var(--lsx-2), var(--lsx-3), var(--lsx-4),
    var(--lsx-5), var(--lsx-6), var(--lsx-7),
    var(--lsx-1), var(--lsx-2), var(--lsx-3), var(--lsx-4),
    var(--lsx-5), var(--lsx-6), var(--lsx-7),
    var(--lsx-1));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2.5px));
  opacity: 0;
  transition: opacity 0.6s var(--ease);
  pointer-events: none;
}

/* Onde sonore : un cercle qui s'écarte et s'efface, en boucle */
.video-toggle .onde {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: 50%;
  border: 1px solid var(--lsx-1);
  opacity: 0;
  pointer-events: none;
}

.video-toggle .onde:nth-of-type(2) { border-color: var(--lsx-2); }

/* --- État actif --- */

.video-toggle[aria-pressed='true'] {
  border-color: transparent;
  color: var(--c-accent);
  background: rgba(14, 11, 8, 0.7);
}

.video-toggle[aria-pressed='true']::before {
  opacity: 1;
  animation: anneau-tourne 7s linear infinite,
             anneau-pulse 2.6s var(--ease) infinite;
}

.video-toggle[aria-pressed='true'] .onde {
  animation: onde-sonore 2.6s var(--ease-out) infinite;
}

.video-toggle[aria-pressed='true'] .onde:nth-of-type(2) { animation-delay: 1.3s; }

@keyframes anneau-tourne {
  to { transform: rotate(1turn); }
}

/* La couronne respire : c'est la variation qui suggère le son */
@keyframes anneau-pulse {
  0%, 100% { filter: brightness(1)   saturate(1); }
  50%      { filter: brightness(1.5) saturate(1.4); }
}

@keyframes onde-sonore {
  0%   { transform: scale(1);    opacity: 0.55; }
  70%  { opacity: 0.12; }
  100% { transform: scale(2.15); opacity: 0; }
}

/* --- État coupé : l'appel ---
   Un arc orange tourne autour du bouton pour inviter à activer le son.
   Un arc qui s'estompe et non un cercle entier, et un tour en 3,2 s : un
   anneau complet tournant vite se lirait comme un chargement en cours.
   L'appel s'arrête dès que le visiteur a activé le son une fois
   (data-son-connu, posé par site.js). */
.video-toggle::after {
  content: '';
  position: absolute;
  inset: -4px;
  z-index: 1;
  border-radius: 50%;
  background: conic-gradient(from 0deg,
    transparent 0deg 200deg,
    rgb(212 97 15 / 0.25) 250deg,
    var(--lsx-1) 350deg,
    transparent 360deg);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  opacity: 0;
  transition: opacity 0.6s var(--ease);
  pointer-events: none;
}

.video-toggle[aria-pressed='false']:not([data-son-connu])::after {
  opacity: 1;
  animation: anneau-tourne 3.2s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  /* Sans mouvement, l'arc reste en place : il signale sans tourner */
  .video-toggle[aria-pressed='false']:not([data-son-connu])::after { animation: none; }
  .video-toggle[aria-pressed='true']::before { animation: none; }
  .video-toggle[aria-pressed='true'] .onde { animation: none; opacity: 0.3; }
}

/* --- La surface se détache ---
   Au départ, elle est posée en haut du hero et défile avec lui : rien ne
   flotte tant qu'on est en haut de page. Une fois sa place d'origine passée
   sous l'en-tête, elle se détache et vient se tenir à mi-hauteur, à droite,
   en glissant depuis le bord — un glissement long et fortement amorti, qui
   ne doit pas attirer l'œil. Le repère invisible, posé par site.js à la place
   d'origine, dit quand la détacher.

   Dans le balisage, la surface est placée juste avant le hero et non dedans :
   le hero isole ses calques (isolation: isolate), et elle passerait sinon
   sous les sections suivantes. Elle n'est jamais déplacée dans la page —
   seule sa classe change — sans quoi l'arc qui tourne autour du bouton
   repartirait de zéro à chaque détachement. */
.video-toggle__repere {
  position: absolute;
  right: var(--gutter);
  top: calc(var(--header-h) + var(--s-4));
  width: 64px; height: 64px;
  visibility: hidden;
  pointer-events: none;
}

/* Détachée du hero, la surface se cale en bas de fenêtre, près du pouce et
   près du défilement, au lieu de flotter à mi-hauteur. À mi-hauteur elle
   passait sur le texte des sections — la colonne ocre de l'accueil en
   particulier — et rien ne justifiait qu'une commande vienne couvrir ce
   qu'on est en train de lire. */
.son-surface--flottant {
  position: fixed;
  top: auto;
  bottom: var(--s-6);
  translate: 0;
  animation: son-glisse 1.1s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes son-glisse {
  from { translate: calc(100% + var(--gutter)) -50%; opacity: 0; }
}

/* Arrivée au pied de page, elle s'efface en fondu pour laisser le pied
   lisible, et revient quand on remonte. */
.son-surface--flottant.son-surface--au-pied {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.5s var(--ease), visibility 0s 0.5s;
}

@media (prefers-reduced-motion: reduce) {
  .son-surface--flottant { animation: none; }
}

/* --- Petits téléphones ---
   Le bouton de son a quitté la barre du haut : il vit désormais sur sa
   surface, en haut du hero puis à mi-hauteur à droite. La barre ne porte donc
   plus que le logo, le rond de contact, les langues et le menu. Elle reste
   serrée sur les petits écrans — le logo ne descend pas sous 200 px et garde
   sa marge de protection —, c'est donc le rond de contact qui se resserre :
   mesuré, 44 px tiennent dès 430 px de large, 36 px dès 375 px, 32 px dès
   360 px. */
:root { --contact-d: 44px; }

@media (max-width: 429px) {
  :root { --contact-d: 36px; }
  .header__inner { gap: var(--s-2); }
}

@media (max-width: 374px) {
  :root { --contact-d: 32px; }
  .header__inner { gap: 6px; }
}

@media (max-width: 1279px) {
  .action-round { width: var(--contact-d); height: var(--contact-d); }
}

.scroll-cue {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(var(--s-7), 7vh, var(--s-9));
  display: none;
  align-items: center;
  gap: var(--s-4);
  font-size: var(--t-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--c-text-muted);
  writing-mode: vertical-rl;
}

@media (min-width: 1080px) { .scroll-cue { display: flex; } }

/* Souris stylisée : le corps, et la molette qui descend puis remonte.
   Le picto lui-même respire légèrement, pour attirer l'œil sans s'agiter. */
.scroll-cue__souris {
  writing-mode: horizontal-tb;   /* le parent est vertical, on rétablit */
  width: 20px;
  height: 32px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  animation: souris-respire 2.8s var(--ease) infinite;
}

.scroll-cue__molette {
  fill: var(--lsx-1);
  stroke: none;
  animation: molette 2.8s var(--ease) infinite;
}

@keyframes molette {
  0%, 100% { transform: translateY(0);   opacity: 0.35; }
  30%      { transform: translateY(5px); opacity: 1; }
  60%      { transform: translateY(9px); opacity: 0; }
  61%      { transform: translateY(0);   opacity: 0; }
}

@keyframes souris-respire {
  0%, 100% { transform: translateY(0); }
  30%      { transform: translateY(3px); }
}

/* Le filet vertical accompagne le mouvement, sous le picto */
.scroll-cue::after {
  content: '';
  width: 1px; height: 48px;
  background: linear-gradient(to bottom, var(--lsx-1), transparent);
  animation: cue 2.8s var(--ease) infinite;
}

@keyframes cue {
  0%   { transform: scaleY(0); transform-origin: top; }
  45%  { transform: scaleY(1); transform-origin: top; }
  55%  { transform: scaleY(1); transform-origin: bottom; }
  100% { transform: scaleY(0); transform-origin: bottom; }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-cue__souris,
  .scroll-cue__molette,
  .scroll-cue::after { animation: none; }
  .scroll-cue__molette { opacity: 1; }
}

/* --- Hero de page intérieure --- */

.page-hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: clamp(400px, 60vh, 640px);
  isolation: isolate;
  overflow: hidden;
  background: var(--c-ink-deep);
}

.page-hero__media { position: absolute; inset: 0; z-index: -2; }

/* Cadrage d'affichage. L'image livrée reste entière — c'est celle de la
   cliente — et chaque page choisit ce que le bandeau en montre, par
   --cadrage posé sur le conteneur. 50 % 50 % centre, 50 % 0 % montre le haut.
   Se règle, se défait, ne touche pas au fichier. */
.page-hero__media img,
.hero__media img { object-position: var(--cadrage, 50% 50%); }

/* --- Bandeau plein écran (page Contact) ---
   La photo occupe tout l'écran et son bas passe sous la section suivante :
   les blocs de contact viennent se poser dessus (.section--sur-photo, qui
   remonte d'autant). Le titre reste au-dessus de cette zone de recouvrement.
   Le voile s'ouvre au milieu et fond la photo dans le fond de page en bas.
   Parallaxe : site.js décale la photo au défilement ([data-parallaxe]). */
:root { --recouvrement-photo: clamp(160px, 32vh, 360px); }

.page-hero--plein {
  min-height: 100vh;
  min-height: 100svh;
}

.page-hero--plein .page-hero__inner {
  padding-bottom: calc(var(--recouvrement-photo) + var(--s-8));
}

.page-hero--plein .page-hero__media { will-change: transform; }

/* Deux voiles : un dégradé depuis la gauche, derrière le titre et le chapô
   (la voûte éclairée les rendrait illisibles), et un dégradé vertical qui
   assombrit sous l'en-tête et fond la photo dans le fond de page en bas. */
.page-hero--plein .page-hero__media::after {
  background:
    linear-gradient(90deg,
      rgb(14 11 8 / 0.78) 0%,
      rgb(14 11 8 / 0.5) 45%,
      rgb(14 11 8 / 0) 78%),
    linear-gradient(180deg,
      rgb(14 11 8 / 0.7) 0%,
      rgb(14 11 8 / 0.2) 28%,
      rgb(14 11 8 / 0.35) 60%,
      rgb(23 19 15 / 0.92) 88%,
      var(--c-bg) 100%);
}

.section--sur-photo {
  position: relative;
  z-index: 1;
  margin-top: calc(-1 * var(--recouvrement-photo));
  padding-top: 0;
}

.page-hero__media img,
.page-hero__media video { width: 100%; height: 100%; object-fit: cover; }

.page-hero__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--halo-texte), var(--veil-page);
}

.page-hero__inner {
  width: 100%;
  max-width: var(--w-max);
  margin-inline: auto;
  padding: calc(var(--header-h) + var(--s-8)) var(--gutter) var(--s-8);
}

.page-hero__title { max-width: 17ch; text-wrap: balance; }
.page-hero__lead { margin-top: var(--s-5); max-width: 54ch; }

/* Légende de la photo du bandeau, sous le chapô : même traitement que les
   légendes de figures (italique, discrète). Le crédit, en romain, ne se
   coupe jamais entre le © et le nom.
   → WordPress : la légende du média mis en avant. */
.page-hero__legende {
  margin-top: var(--s-4);
  max-width: 60ch;
  font-size: var(--t-micro);
  font-style: italic;
  line-height: 1.45;
  color: var(--c-text-muted);
  text-wrap: pretty;
}

.page-hero__credit { font-style: normal; white-space: nowrap; color: var(--c-text); }

/* Photo trop claire pour le texte posé dessus : on l'estompe sur le fond
   sombre du bandeau. */
.page-hero--sombre .page-hero__media img { opacity: 0.55; }


/* =========================================================================
   6 bis. MATIÈRES DE FOND
   Pose un visuel de scénographie derrière le contenu, en couche isolée.
   Inerte tant qu'aucune matière n'est déclarée :

     <section class="section textured" style="--texture:url(../assets/img/matieres/1.jpg)">

   Le dosage se règle par --texture-opacity et --texture-blend (tokens.css),
   redéfinissables élément par élément.
   ========================================================================= */

.textured { position: relative; isolation: isolate; }

.textured::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--texture, none);
  background-size: var(--texture-size);
  background-position: var(--texture-pos);
  background-repeat: var(--texture-repeat);
  opacity: var(--texture-opacity);
  mix-blend-mode: var(--texture-blend);
  pointer-events: none;
}

/* Estompe la matière sur les bords, pour qu'elle ne coupe pas net */
.textured--fade::before {
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
}


/* -------------------------------------------------------------------------
   MATIÈRES APPLIQUÉES AU SITE
   Posées par le CSS seul, sans rien changer au balisage des pages.

   Trois plans, qui donnent son rythme au défilement :
     · fond général  — matière 2, fixe, visible derrière les sections neutres
     · sections alternées — matière 1, qui défile avec la page
     · pied de page  — matière 3, dont le halo referme la lecture

   Le dosage se règle depuis tokens.css (--texture-page, --texture-alt,
   --texture-footer). Les fichiers sont les versions optimisées de opt/.
   ------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------
   LUMIÈRES D'EXPOSITION
   Des sources chaudes veillent sur les côtés, comme les projecteurs qui
   éclairent une paroi. Elles dérivent lentement au défilement : on ne les
   voit pas bouger, on a le sentiment de les longer.

   Aucun filter: blur — les dégradés radiaux sont flous par nature et bien
   moins coûteux à composer. Les halos sont posés en couche fixe, sous les
   matières de fond, donc masqués par les sections opaques.
   ------------------------------------------------------------------------- */

.lumieres {
  position: fixed;
  inset: 0;
  z-index: -8;
  overflow: hidden;
  pointer-events: none;
}

.lumiere {
  position: absolute;
  width: 62vw;
  aspect-ratio: 1;
  will-change: transform;
}

/* Chaque source a sa teinte, sa taille et sa vitesse propres : trois halos
   identiques auraient l'air d'un motif, non d'un éclairage. */
.lumiere--1 {
  left: -30vw;
  top: -8vh;
  background: radial-gradient(circle at center,
    rgba(212, 97, 15, 0.17) 0%, rgba(212, 97, 15, 0) 62%);
  transform: translateY(calc(var(--defile, 0) * -34vh));
}

.lumiere--2 {
  right: -34vw;
  top: 26vh;
  width: 70vw;
  background: radial-gradient(circle at center,
    rgba(201, 146, 34, 0.13) 0%, rgba(201, 146, 34, 0) 60%);
  transform: translateY(calc(var(--defile, 0) * 48vh));
}

.lumiere--3 {
  left: -22vw;
  bottom: -22vh;
  width: 52vw;
  background: radial-gradient(circle at center,
    rgba(183, 37, 29, 0.11) 0%, rgba(183, 37, 29, 0) 58%);
  transform: translateY(calc(var(--defile, 0) * -22vh));
}

@media (max-width: 700px) {
  /* Sur petit écran les halos se recouvrent et brouillent le fond */
  .lumiere--3 { display: none; }
  .lumiere { width: 92vw; }
}

@media (prefers-reduced-motion: reduce) {
  .lumiere { transform: none !important; }
}


/* --- Fond général, fixe --- */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -10;
  background-image: url('../img/matieres/opt/2.jpg');
  background-size: cover;
  background-position: center;
  opacity: var(--texture-page);
  mix-blend-mode: screen;
  pointer-events: none;
}

/* --- Sections alternées --- */
.section--alt { isolation: isolate; }

.section--alt::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: url('../img/matieres/opt/1.jpg');
  background-size: cover;
  background-position: center;
  opacity: var(--texture-alt);
  mix-blend-mode: screen;
  pointer-events: none;
}

/* --- Pied de page --- */
.footer { position: relative; isolation: isolate; }

.footer::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--papier-matiere);
  background-size: cover;
  background-position: center 30%;
  opacity: var(--papier-opacite);
  /* Sur fond clair, « multiply » creuse la matière ; « screen » l'effacerait */
  mix-blend-mode: multiply;
  pointer-events: none;
}

/* Voile de lisibilité, plus dense là où court le texte */
.footer::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg,
    rgba(228, 218, 197, 0.90) 0%,
    rgba(228, 218, 197, 0.62) 40%,
    rgba(228, 218, 197, 0.92) 100%);
  pointer-events: none;
}

/* Le hero et les bandeaux vidéo portent déjà leur propre image : on n'y
   ajoute pas de matière, elle brouillerait la lecture du titre. */


/* -------------------------------------------------------------------------
   SECTION CLAIRE — la rupture de papier
   Une section sur fond de papier au milieu du parcours sombre : le contraste
   relance la lecture et rappelle le fond des visuels de scénographie.

   Le principe tient en une chose : la section redéfinit les RÔLES de couleur
   dans sa portée. Les composants qui s'appuient sur ces rôles — cartes,
   sur-titres, bordures, textes — basculent d'eux-mêmes, sans qu'aucun d'eux
   n'ait besoin d'une variante claire.

   Attention aux accents : sur ce papier, l'ocre --lsx-2 tombe à 1,99:1 et
   l'orange --lsx-1 à 2,74:1. Seuls le brun ocre et le rouge brique tiennent
   comme couleur de texte ; l'orange reste réservé aux aplats.

   Matière au choix, par --papier-matiere : 10 (paysage), 13 (œil animal),
   20 (arbre et éclaboussures).
   ------------------------------------------------------------------------- */

.section--papier {
  --papier-fond:     #E4DAC5;
  --papier-matiere:  url('../img/matieres/opt/10.jpg');
  --papier-opacite:  0.5;

  /* Rôles inversés */
  --c-text:          #3A2D1E;   /* 9,61:1 sur le papier */
  --c-text-muted:    #6B5A44;   /* 4,77:1 */
  --c-accent:        var(--lsx-5);   /* brun ocre — 4,63:1 */
  --c-surface:       rgba(255, 252, 245, 0.55);
  --c-border:        rgba(58, 45, 30, 0.22);
  --c-border-soft:   rgba(58, 45, 30, 0.11);
  --c-border-warm:   rgba(138, 81, 25, 0.45);
  --c-bone:          #2E2416;   /* les emphases deviennent sombres */
  --c-bone-2:        #4A3B28;
  --c-bone-3:        #6B5A44;

  position: relative;
  isolation: isolate;
  background-color: var(--papier-fond);
  color: var(--c-text);
}

.section--papier::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--papier-matiere);
  background-size: cover;
  background-position: center;
  opacity: var(--papier-opacite);
  mix-blend-mode: multiply;   /* sur fond clair, « multiply » creuse la matière */
  pointer-events: none;
}

/* Le voile éclaircit la zone de texte sans effacer la matière autour */
.section--papier::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg,
    rgba(228, 218, 197, 0.88) 0%,
    rgba(228, 218, 197, 0.55) 45%,
    rgba(228, 218, 197, 0.88) 100%);
  pointer-events: none;
}

/* Le filet du sur-titre perd son trait le plus sombre, invisible ici */
.section--papier .eyebrow::before {
  background-image:
    linear-gradient(var(--lsx-3), var(--lsx-3)),
    linear-gradient(var(--lsx-5), var(--lsx-5)),
    linear-gradient(var(--lsx-1), var(--lsx-1));
}

/* Les cartes deviennent des cartons posés sur le papier */
.section--papier .card {
  background: var(--c-surface);
  border-color: rgba(58, 45, 30, 0.16);
  box-shadow: 0 2px 14px -8px rgba(58, 45, 30, 0.4);
  /* Sur le papier, s'effacer veut dire s'éclaircir : les contours tendent
     vers la couleur du papier. */
  --cadre-2: color-mix(in srgb, var(--lsx-5) 70%, var(--papier-fond));
  --cadre-3: color-mix(in srgb, var(--lsx-5) 40%, var(--papier-fond));
}

.section--papier a.card:hover,
.section--papier .card:has(a:hover) { border-color: var(--lsx-3); }

.section--papier .card__title { color: var(--c-text); }

/* Le bouton fantôme n'est plus lisible en calcaire */
/* Même geste sur le papier clair, mais au brun ocre : l'orange plein y serait
   criard, et le texte doit rester en réserve claire sur l'aplat. */
.section--papier .btn--ghost { border-color: rgba(58, 45, 30, 0.3); color: #3A2D1E; }
.section--papier .btn--ghost:hover,
.section--papier .btn--ghost:focus-visible {
  background: var(--lsx-5);
  border-color: var(--lsx-5);
  color: #FFFCF5;
}

.section--papier .stat { border-top-color: rgba(138, 81, 25, 0.4); }
.section--papier .stat__num { -webkit-text-stroke-color: var(--lsx-5); }
.section--papier .stat__num::before { -webkit-text-stroke-color: var(--lsx-3); }
.section--papier .stat__num::after  { -webkit-text-stroke-color: var(--lsx-6); }

/* La matière de fond générale ne doit pas transparaître ici */
.section--papier.section--alt { background-color: var(--papier-fond); }


/* =========================================================================
   7. BANDEAU VIDÉO DE SECTION (immersion en cours de page)
   ========================================================================= */

.media-band {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--c-ink-deep);
  min-height: clamp(420px, 70vh, 760px);
  display: flex;
  align-items: center;
}

.media-band__media { position: absolute; inset: 0; z-index: -2; }

.media-band__media video,
.media-band__media img { width: 100%; height: 100%; object-fit: cover; }

.media-band__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--halo-texte), var(--veil-flat);
}

/* --- Bandeau en fondu ---
   Trois vues du chantier se succèdent au lieu d'une seule image fixe. Le
   fondu est en CSS seul : aucune minuterie en JavaScript, et si le visiteur
   a demandé moins de mouvement il ne reste que la première vue.

   Chaque image garde sa dérive Ken Burns : les deux animations sont donc
   déclarées ensemble — une propriété animation en écrase une autre, elles ne
   s'additionnent pas. Les retards sont écrits par paire, dans le même ordre.

   Rythme : une vue toutes les cinq secondes, un fondu d'une seconde et demie,
   soit une boucle de quinze secondes. Le premier retard est négatif pour que
   la première vue soit déjà pleinement visible au chargement. */

.media-band__media--fondu { --fondu-boucle: 15s; }

.media-band__media--fondu img {
  position: absolute;
  inset: 0;
  opacity: 0;
  animation: kenburns var(--kb-duree) ease-in-out infinite alternate,
             bandeau-fondu var(--fondu-boucle) var(--ease) infinite;
}

.media-band__media--fondu img:nth-child(1) { opacity: 1; animation-delay: -9s,  -1.5s; }
.media-band__media--fondu img:nth-child(2) {              animation-delay: -15s,  3.5s; }
.media-band__media--fondu img:nth-child(3) {              animation-delay: -22s,  8.5s; }

/* Une vue entre en fondu, tient cinq secondes, puis s'efface — sous la
   suivante, déjà opaque : la succession se lit sans jamais de trou. */
@keyframes bandeau-fondu {
  0%     { opacity: 0; }
  10%    { opacity: 1; }
  33.33% { opacity: 1; }
  43.33% { opacity: 0; }
  100%   { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .media-band__media--fondu img { animation: none; }
  .media-band__media--fondu img:nth-child(1) { opacity: 1; transform: scale(var(--kb-depart)); }
  .media-band__media--fondu img + img { opacity: 0; }
}

.media-band__inner {
  width: 100%;
  max-width: var(--w-max);
  margin-inline: auto;
  padding: clamp(var(--s-8), 10vh, var(--s-10)) var(--gutter);
}

.media-band__content { position: relative; max-width: 46ch; }


/* =========================================================================
   8. COMPTE À REBOURS
   ========================================================================= */

/* --- Le compte à rebours et sa ville ------------------------------------
   Deux colonnes : la silhouette de la ville d'accueil à gauche, le décompte
   à droite, séparées d'un filet. On annonce ainsi un lieu autant qu'une date.

   Sous 680 px la colonne d'image passe au-dessus et le filet devient
   horizontal : côte à côte, aucune des deux n'aurait plus la place de se
   lire. */

.countdown-bloc {
  display: grid;
  gap: clamp(var(--s-4), 3vw, var(--s-6));
  align-items: center;
}

@media (min-width: 680px) {
  .countdown-bloc {
    grid-template-columns: auto 1px 1fr;
    justify-content: start;
  }
}

.countdown-bloc__filet {
  align-self: stretch;
  background: var(--c-border);
}

@media (max-width: 679px) {
  .countdown-bloc__filet { height: 1px; }
}

/* Silhouette dessinée, en trois plans et trois couleurs de la charte : brun
   ocre au lointain, orange pour les tours, rouge brique pour la rive et l'eau
   — l'ordre même des traits du logotype. Dessin vectoriel plutôt qu'image :
   net à toute taille, sans requête réseau, et rien à racheter. */
.countdown-bloc__ville {
  display: block;
  width: clamp(180px, 26vw, 280px);
  height: auto;
  /* Retenu pour rester un décor et non un second sujet à côté des chiffres. */
  opacity: 0.9;
}

.countdown { display: flex; align-items: flex-start; gap: clamp(var(--s-4), 3vw, var(--s-6)); }

.countdown__unit { text-align: center; min-width: 3.5ch; }

.countdown__num {
  display: block;
  font-family: var(--f-display);
  font-size: clamp(1.7rem, 3.4vw, 2.6rem);
  font-weight: 700;
  line-height: 1;
  color: var(--c-bone);
}

.countdown__label {
  display: block;
  margin-top: var(--s-2);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

/* La ville d'accueil, énoncée avant tout le reste : c'est elle qu'on retient
   d'un compte à rebours, non le nom de l'institution. Portée au calcaire et
   au corps des titres, elle domine ; la mention du musée passe dessous, en
   petit, et le décompte suit. */
.countdown__ville {
  font-family: var(--f-display);
  font-size: clamp(1.9rem, 4vw, 3rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-title);
  text-transform: uppercase;
  color: var(--c-bone);
  margin-bottom: var(--s-2);
}

.countdown__caption {
  font-size: var(--t-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--c-accent);
  margin-bottom: var(--s-4);
}

.countdown__caption strong {
  font-weight: 700;
  color: var(--c-bone);
  letter-spacing: var(--ls-micro);
}

/* --- Les secondes battent ---
   Une lueur ocre qui s'allume à chaque seconde puis retombe : le compte à
   rebours cesse d'être un affichage figé, il donne le pouls de l'attente.
   L'animation est relancée par site.js à chaque changement de valeur, de
   sorte que la pulsation reste calée sur le battement réel. */

.countdown__unit[data-unit="seconds"] .countdown__num {
  position: relative;
  color: var(--c-accent);
}

.countdown__unit[data-unit="seconds"].is-tick .countdown__num {
  animation: battement 1s var(--ease-out);
}

@keyframes battement {
  0% {
    color: #F6D89A;
    text-shadow: 0 0 18px rgba(212, 97, 15, 0.85),
                 0 0 42px rgba(201, 146, 34, 0.45);
  }
  100% {
    color: var(--c-accent);
    text-shadow: 0 0 0 rgba(212, 97, 15, 0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .countdown__unit[data-unit="seconds"].is-tick .countdown__num { animation: none; }
}


/* =========================================================================
   9. CHIFFRES CLÉS
   ========================================================================= */

.stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-6) var(--s-5); }

@media (min-width: 760px) { .stats { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.stat { border-top: 1px solid var(--c-border-warm); padding-top: var(--s-4); }

/* --- Chiffres clés en contour ---
   Transposition du logotype : le nombre est vidé, son contour dessiné, puis
   redoublé deux fois en retrait dans des teintes plus profondes. On retrouve
   le faisceau de traits parallèles des lettres du logo.

   Pour revenir à des chiffres pleins, il suffit de retirer .stat__num::before
   et ::after et de rendre sa couleur au texte. */

.stat__num {
  position: relative;
  display: block;
  font-family: var(--f-chiffres);
  font-size: clamp(2rem, 4.6vw, 3.6rem);
  font-weight: 700;
  letter-spacing: -0.02em;   /* une grotesque en gros corps se resserre */
  line-height: 1;
  color: transparent;
  /* Trait médian : la valeur de référence */
  -webkit-text-stroke: var(--stat-trait) var(--lsx-2);
  text-stroke: var(--stat-trait) var(--lsx-2);
  /* Le tracé déborde du texte : on lui laisse la place à droite */
  padding-right: calc(var(--stat-ecart) * 2);
}

.stat__num::before,
.stat__num::after {
  content: attr(data-valeur);
  position: absolute;
  left: 0;
  top: 0;
  z-index: -1;
  color: transparent;
  pointer-events: none;
}

/* --p est publiée par site.js sur chaque nombre : 1 quand il traverse le
   milieu de la fenêtre, 0 aux bords. On s'en sert à l'envers — l'écartement
   est ce qu'il reste à parcourir avant le centre — de sorte que le faisceau
   se rassemble au moment où on le regarde.
   Sa valeur par défaut est 1 : sans JavaScript, le chiffre s'affiche dans son
   état rassemblé, le plus lisible des deux. */
.stat__num {
  --ecartement: calc(1 - var(--p, 1));
}

/* L'écart de base suit lui aussi le mouvement, au lieu de rester constant :
   sans cela il subsistait 3,5 et 7 px de décalage au passage au centre, et le
   faisceau ne se refermait jamais tout à fait. Les trois traits se superposent
   maintenant exactement, puis se déploient à mesure qu'on s'éloigne. */
.stat__num::before {
  /* Un rien plus épais que le trait de tête */
  -webkit-text-stroke: calc(var(--stat-trait) * 1.35) var(--lsx-1);
  text-stroke: calc(var(--stat-trait) * 1.35) var(--lsx-1);
  transform: translate(
    calc((var(--stat-ecart) + var(--stat-course)) * var(--ecartement)),
    calc(var(--stat-course) * 0.4 * var(--ecartement)));
  opacity: calc(0.28 + 0.52 * var(--p, 1));
}

/* Troisième trait, le plus profond : il s'écarte deux fois plus, ce qui
   creuse la perspective à mesure que le chiffre s'éloigne du centre. */
.stat__num::after {
  /* Le plus ténu des trois : il s'efface dans la profondeur */
  -webkit-text-stroke: calc(var(--stat-trait) * 0.7) var(--lsx-5);
  text-stroke: calc(var(--stat-trait) * 0.7) var(--lsx-5);
  transform: translate(
    calc((var(--stat-ecart) * 2 + var(--stat-course) * 2) * var(--ecartement)),
    calc(var(--stat-course) * 0.8 * var(--ecartement)));
  opacity: calc(0.18 + 0.44 * var(--p, 1));
}

/* Sous 600 px les chiffres rapetissent : le contour deviendrait filandreux
   et les traits se chevaucheraient. On revient au plein. */
@media (max-width: 600px) {
  .stat__num {
    color: var(--c-accent);
    -webkit-text-stroke: 0;
    text-stroke: 0;
    padding-right: 0;
  }
  .stat__num::before,
  .stat__num::after { display: none; }
}

.stat__label {
  display: block;
  margin-top: var(--s-3);
  font-size: var(--t-small);
  line-height: 1.35;
  color: var(--c-text-muted);
}


/* =========================================================================
   10. CARTES, GRILLES, MÉDIAS
   ========================================================================= */

.grid { display: grid; gap: clamp(var(--s-4), 2vw, var(--s-6)); }

.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); }

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--c-surface);
  border: 1px solid var(--c-border-soft);
  border-radius: var(--radius);
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease),
              --cadre-pas 0.6s var(--ease);
}

a.card:hover, .card:has(a:hover) { border-color: var(--lsx-1); transform: translateY(-4px); }

.card__media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
  background: var(--c-ink-2);
}

/* Sur la page À propos, les deux premières cartes portent une vignette de
   galerie en 16/9 : la troisième, simple photographie, adopte le même format
   et le même voile pour que la rangée se tienne. Sans lui, sa photo paraissait
   crue à côté des deux autres. */
.card__media--large { aspect-ratio: 16 / 9; }

/* La Réalité virtuelle est une option, pas un neuvième module. Elle reste
   dans la grille, au même rang que les autres, et c'est son contour qui le
   dit : l'orange des actions du site, là où les huit modules portent un filet
   presque invisible. Rien d'autre ne change — même fond, même mise en page.
   Le survol des cartes allume déjà cet orange : l'option a simplement cet
   état-là au repos. */
.card--option {
  border-color: var(--lsx-1);
}

.card--option .card__meta { color: var(--lsx-1); }

/* Une vignette de galerie posée dans une carte de module : elle épouse le
   cadre de la carte au lieu d'imposer son propre 16/9 et son propre rayon.
   Les modules 07 et 08 ont plusieurs vues ; la carte les ouvre, les autres
   restent de simples photographies. */
.card__media .media-vignette {
  position: absolute;
  inset: 0;
  aspect-ratio: auto;
  border-radius: 0;
}

.card__media--large img { opacity: 0.86; transition: transform var(--dur-slow) var(--ease-out), opacity var(--dur) var(--ease); }
.card:hover .card__media--large img { opacity: 1; }

.card__media--large::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--veil-vignette);
  pointer-events: none;
}

.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-slow) var(--ease-out); }
.card:hover .card__media img { transform: scale(1.05); }

/* Au survol, la bordure de la carte se démultiplie vers la droite et le bas :
   deux contours décalés, sans fond, sortent de derrière elle, comme les
   traits parallèles du logotype. Chacun est plus sombre que le précédent,
   pour que la série s'efface en s'éloignant : orange (la bordure), rouge
   sombre, brun très foncé — luminances mesurées 0,226 → 0,067 → 0,028.
   Le brun foncé (--lsx-6, 0,073) ne convient pas en dernier : il est un peu
   plus clair que le rouge sombre.

   Chaque contour est un pseudo-élément de la taille de la carte, décalé de
   --cadre-pas (puis du double). Un clip-path n'en garde que la partie qui
   dépasse de la carte, à droite et en bas : le contour ne passe jamais sur
   son contenu. --cadre-pas est déclaré avec @property pour pouvoir être
   animé : les contours glissent et apparaissent en fondu, lentement, et
   repartent un peu plus vite. */
@property --cadre-pas {
  syntax: '<length>';
  inherits: true;
  initial-value: 0px;
}

.card {
  --cadre-2: var(--lsx-4);
  --cadre-3: var(--lsx-7);
}

.card::before,
.card::after {
  --d: var(--cadre-pas);
  content: '';
  position: absolute;
  inset: -1px;
  border: 1px solid transparent;
  border-radius: inherit;
  pointer-events: none;
  translate: var(--d) var(--d);
  clip-path: polygon(
    calc(100% - var(--d)) 0, 100% 0, 100% 100%, 0 100%,
    0 calc(100% - var(--d)), calc(100% - var(--d)) calc(100% - var(--d)));
  transition: border-color 0.6s var(--ease);
}

.card::after { --d: calc(var(--cadre-pas) * 2); }

a.card:hover, .card:has(a:hover),
a.card:focus-visible, .card:has(a:focus-visible) {
  --cadre-pas: 5px;
  transition: border-color var(--dur) var(--ease), transform var(--dur-slow) var(--ease-out),
              --cadre-pas 1.1s var(--ease-out);
}

a.card:hover::before, .card:has(a:hover)::before,
a.card:focus-visible::before, .card:has(a:focus-visible)::before {
  border-color: var(--cadre-2);
  transition: border-color 1.1s var(--ease-out);
}

a.card:hover::after, .card:has(a:hover)::after,
a.card:focus-visible::after, .card:has(a:focus-visible)::after {
  border-color: var(--cadre-3);
  transition: border-color 1.1s var(--ease-out);
}

.card__body { display: flex; flex-direction: column; gap: var(--s-3); padding: var(--s-5); flex: 1; }

.card__meta {
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-accent);
}

/* Crédit photographique, posé sous l'image de la carte. Même micro-corps que
   les légendes, mais en romain et sans capitales : un crédit se lit s'il est
   cherché, il ne s'annonce pas. Le bloc n'existe que si le crédit est connu —
   les cartes dont nous n'avons pas l'auteur n'affichent rien.
   → WordPress : la légende du média mis en avant. */
/* Le crédit appartient à l'image, pas au texte : il remonte se coller sous
   elle, et l'espace ainsi libéré passe devant le libellé du module, qui ouvre
   vraiment le contenu de la carte. */
.card__credit {
  margin: calc(var(--s-2) - var(--s-5)) 0 var(--s-3);
  font-size: var(--t-micro);
  line-height: 1.4;
  color: var(--c-text-muted);
}

.card__title {
  font-family: var(--f-display);
  font-size: var(--t-h4);
  font-weight: 700;
  line-height: 1.3;
}

/* Le surtitre et le titre forment un seul geste : ils se resserrent l'un sur
   l'autre, plus qu'ils ne se séparent du reste du corps de la carte. */
.card__meta + .card__title { margin-top: calc(var(--s-3) / -2); }

.card__text { font-size: var(--t-small); line-height: 1.5; color: var(--c-text-muted); }

.card__body .link-arrow { margin-top: auto; padding-top: var(--s-2); }

/* Numérotation des modules d'exposition */
.card__index {
  font-family: var(--f-display);
  font-size: var(--t-small);
  color: var(--lsx-1);
  letter-spacing: 0.1em;
}

.figure { margin: 0; }
.figure img { width: 100%; border-radius: var(--radius); background: var(--c-ink-2); }

/* --- Vidéo hébergée : vignette, puis lecture en surimpression ---
   Rien de Vimeo n'est chargé tant que le visiteur n'a pas cliqué : ni le
   lecteur, ni ses scripts, ni le moindre cookie. La vignette reste une image
   du site ; le lecteur ne s'ouvre qu'à la demande, par-dessus la page. */

.video-vignette,
.media-vignette {
  --vignette-trame: 0.86;
  --vignette-trame-survol: 1;
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--c-ink-deep);
  cursor: pointer;
}

/* L'image ne s'affiche pas en photo pleine mais en trame : atténuée, elle
   devient une matière parmi les autres et laisse le bouton de lecture
   prendre la main. Elle se révèle au survol. */
.video-vignette img,
.media-vignette img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: var(--vignette-trame, 0.42);
  /* La vignette de galerie garde sa photographie presque entière : le disque
     qui la couvrait a disparu, plus rien ne justifie de l'atténuer. */
  transition: transform var(--dur-slow) var(--ease-out),
              opacity var(--dur) var(--ease);
}

.video-vignette:hover img,
.media-vignette:hover img {
  transform: scale(1.04);
  opacity: var(--vignette-trame-survol, 0.72);
}

/* Voile chaud : il assoit la trame sur le noir du site et fait ressortir
   le bouton, au lieu de laisser l'image flotter. */
.video-vignette::after,
.media-vignette::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--veil-vignette);
  pointer-events: none;
  transition: opacity var(--dur) var(--ease);
}

.video-vignette:hover::after,
.media-vignette:hover::after { opacity: 0.65; }

/* Le bouton de lecture reprend l'aplat orange vers rouge du rond de contact */
.video-vignette__play {
  position: absolute;
  z-index: 2;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  width: clamp(58px, 7vw, 76px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--lsx-1) 0%, var(--lsx-3) 100%);
  color: var(--c-bone);
  box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.7);
  transition: transform var(--dur) var(--ease-out), background var(--dur) var(--ease);
}

/* Le diaporama du montage est une vignette de galerie, mais ce qu'elle ouvre
   est une suite de vidéos : elle porte donc le même disque de lecture, et
   répond au survol de la même façon. */
.video-vignette:hover .video-vignette__play,
.media-vignette:hover .video-vignette__play {
  transform: translate(-50%, -50%) scale(1.09);
  background: linear-gradient(135deg, var(--lsx-3) 0%, var(--lsx-4) 100%);
}

.video-vignette__play svg { margin-left: 3px; }   /* le triangle est optiquement décentré */

/* Onde d'appel, discrète */
.video-vignette__play::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--lsx-1);
  animation: onde-sonore 3s var(--ease-out) infinite;
}

.video-vignette__duree {
  position: absolute;
  z-index: 2;
  right: var(--s-4);
  bottom: var(--s-4);
  padding: 4px 10px;
  border-radius: var(--radius-s);
  background: rgba(14, 11, 8, 0.72);
  backdrop-filter: blur(6px);
  font-size: var(--t-micro);
  letter-spacing: 0.1em;
  color: var(--c-bone);
}


/* --- Le lecteur, par-dessus la page --- */

/* Le dialogue occupe tout l'écran et centre son cadre lui-même : laissé au
   navigateur, le positionnement varie d'un moteur à l'autre. */
.video-modal {
  position: fixed;
  inset: 0;
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: hidden;
  color: var(--c-bone);
}

.video-modal[open] {
  display: grid;
  place-items: center;
}

.video-modal::backdrop {
  /* Le dégradé plat est posé PAR-DESSUS la matière : en CSS l'image de fond
     recouvre la couleur, il faut donc un calque explicite pour la voiler. */
  background:
    linear-gradient(rgb(226 217 197 / var(--modal-voile)),
                    rgb(226 217 197 / var(--modal-voile))),
    var(--modal-matiere) center / cover no-repeat,
    var(--modal-base);
  backdrop-filter: blur(10px);
}

/* Le cadre garde le format 16/9 en toutes circonstances : la largeur cède
   quand la hauteur d'écran ne suffit pas, plutôt que de rogner l'image. */
.video-modal__frame {
  position: relative;
  width: min(92vw, 1240px);
  max-width: calc(82vh * 16 / 9);
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  background: #000;
  box-shadow: 0 34px 90px -22px rgba(38, 28, 18, 0.62),
              0 0 0 1px rgba(58, 45, 30, 0.14);
}

.video-modal__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Fermeture en haut à droite de l'écran, hors du cadre : elle ne recouvre
   jamais les commandes du lecteur, qui occupent le bas de la vidéo. */
.video-modal__close {
  position: fixed;
  top: clamp(var(--s-4), 3vh, var(--s-6));
  right: clamp(var(--s-4), 3vw, var(--s-6));
  z-index: 2;
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border: 1px solid rgba(58, 45, 30, 0.3);
  border-radius: 50%;
  background: rgba(255, 252, 245, 0.72);
  backdrop-filter: blur(6px);
  color: #3A2D1E;
  transition: border-color var(--dur) var(--ease),
              color var(--dur) var(--ease),
              background var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}

.video-modal__close:hover {
  border-color: var(--lsx-3);
  background: #FFFCF5;
  color: var(--lsx-3);
  transform: rotate(90deg);
}

@media (prefers-reduced-motion: reduce) {
  .video-vignette__play::before { animation: none; opacity: 0.4; }
}


/* -------------------------------------------------------------------------
   GALERIE D'IMAGES
   Même principe que la vidéo : une vignette en trame, un picto qui annonce
   la nature du contenu, et l'ouverture d'une visionneuse par-dessus la page.
   Le picto de galerie remplace le triangle de lecture ; le reste est commun.
   ------------------------------------------------------------------------- */

/* Le picto de galerie tenait un grand disque orange au milieu de la vignette.
   Il annonçait bien le diaporama, mais couvrait le sujet de la photographie —
   la charpente de Lascaux II, la vue aérienne de Lascaux IV. Il rejoint donc
   l'étiquette du bas, à gauche du nombre de vues : la même information, au
   même endroit, et la photographie reste entière. */
.media-vignette__picto {
  display: inline-grid;
  place-items: center;
  color: var(--c-accent);
  transition: color var(--dur) var(--ease);
}

.media-vignette__picto svg { display: block; width: 17px; height: auto; }

.media-vignette:hover .media-vignette__picto { color: var(--lsx-1); }

/* Étiquette du bas : le picto, puis le nombre de vues. */
.media-vignette__compte {
  position: absolute;
  z-index: 2;
  right: var(--s-4);
  bottom: var(--s-4);
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  padding: 6px 13px;
  border-radius: 999px;
  background: rgba(14, 11, 8, 0.72);
  backdrop-filter: blur(6px);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-bone);
}

/* La liste source reste dans le document — les images sont indexables et
   restent accessibles sans JavaScript — mais n'est pas affichée. */
.gallery-source { display: none; }


/* --- La visionneuse --- */

.lightbox {
  position: fixed;
  inset: 0;
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  /* La matière est portée par le dialogue lui-même, non par ::backdrop :
     ce pseudo-élément n'hérite pas des variables posées sur le dialogue
     dans les navigateurs antérieurs à 2024, et le fond y serait perdu. */
  background:
    linear-gradient(rgb(14 11 8 / var(--diapo-voile)),
                    rgb(14 11 8 / var(--diapo-voile))),
    var(--diapo-matiere) center / cover no-repeat,
    var(--diapo-base);
  overflow: hidden;
}

.lightbox[open] {
  display: grid;
  grid-template-rows: 1fr auto;
  place-items: center;
}

/* Les trois parois du diaporama. site.js pose data-paroi au hasard à chaque
   ouverture ; les chemins restent ici, résolus depuis cette feuille de style,
   donc justes quel que soit le dossier de la page. */
.lightbox[data-paroi='1'] { --diapo-matiere: url('../img/matieres/opt/1.jpg'); }
.lightbox[data-paroi='2'] { --diapo-matiere: url('../img/matieres/opt/2.jpg'); }
.lightbox[data-paroi='3'] { --diapo-matiere: url('../img/matieres/opt/3.jpg'); }

.lightbox::backdrop {
  background: rgb(10 8 6 / 0.9);
  backdrop-filter: blur(10px);
}

.lightbox__scene {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  padding: clamp(var(--s-6), 8vh, var(--s-9)) clamp(var(--s-5), 9vw, var(--s-10));
}

.lightbox__figure {
  margin: 0;
  display: grid;
  gap: var(--s-4);
  justify-items: center;
  max-width: 100%;
}

.lightbox__figure img {
  max-width: 100%;
  max-height: 72vh;
  width: auto;
  border-radius: var(--radius);
  /* Sur fond sombre, l'ombre portée ne se voit plus : c'est un filet clair
     qui détache la photographie de la paroi. */
  box-shadow: 0 40px 100px -24px rgb(0 0 0 / 0.75),
              0 0 0 1px rgb(242 237 228 / 0.14);
}

.lightbox__figure video {
  max-width: 100%;
  max-height: 72vh;
  width: auto;
  border-radius: var(--radius);
  background: #000;
  box-shadow: 0 40px 100px -24px rgb(0 0 0 / 0.75),
              0 0 0 1px rgb(242 237 228 / 0.14);
}

/* Lecteur Vimeo embarqué : le cadre garde le 16/9 et cède en largeur quand
   la hauteur d'écran ne suffit pas, comme celui du reportage. */
.lightbox__cadre {
  position: relative;
  width: min(92vw, 1240px);
  max-width: calc(72vh * 16 / 9);
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  background: #000;
  box-shadow: 0 40px 100px -24px rgb(0 0 0 / 0.75),
              0 0 0 1px rgb(242 237 228 / 0.14);
}

.lightbox__cadre iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.lightbox__legende {
  max-width: 62ch;
  text-align: center;
  font-size: var(--t-small);
  font-style: italic;
  line-height: 1.5;
  color: var(--c-bone-2);   /* calcaire ombré — 9,6:1 sur le fond du diaporama */
}

/* Un lien peut accompagner la légende — par exemple, depuis le diaporama du
   montage, vers le mur de photos de l'équipe. */
.lightbox__legende a {
  color: var(--c-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.lightbox__legende a:hover { color: var(--lsx-1); }

/* Boutons : rond sombre translucide, à l'inverse du lecteur vidéo, qui lui
   s'ouvre sur papier clair. */
.lightbox__btn {
  position: fixed;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border: 1px solid rgb(242 237 228 / 0.28);
  border-radius: 50%;
  background: rgb(20 16 12 / 0.62);
  backdrop-filter: blur(6px);
  color: var(--c-bone);
  transition: border-color var(--dur) var(--ease),
              background var(--dur) var(--ease),
              color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}

.lightbox__btn:hover {
  border-color: var(--c-accent);
  background: rgb(20 16 12 / 0.85);
  color: var(--c-accent);
}

.lightbox__btn--close {
  top: clamp(var(--s-4), 3vh, var(--s-6));
  right: clamp(var(--s-4), 3vw, var(--s-6));
}
.lightbox__btn--close:hover { transform: rotate(90deg); }

.lightbox__btn--prev,
.lightbox__btn--next { top: 50%; transform: translateY(-50%); }

.lightbox__btn--prev { left: clamp(var(--s-3), 2.5vw, var(--s-6)); }
.lightbox__btn--next { right: clamp(var(--s-3), 2.5vw, var(--s-6)); }

.lightbox__btn--prev:hover { transform: translateY(-50%) translateX(-3px); }
.lightbox__btn--next:hover { transform: translateY(-50%) translateX(3px); }

.lightbox__btn[disabled] { opacity: 0.3; pointer-events: none; }

/* Pagination : des traits, dans l'esprit du logotype */
.lightbox__pagination {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-bottom: clamp(var(--s-5), 4vh, var(--s-7));
}

.lightbox__puce {
  width: 22px;
  height: 2px;
  border: 0;
  padding: 0;
  background: rgb(242 237 228 / 0.26);
  transition: background var(--dur) var(--ease), width var(--dur) var(--ease);
}

.lightbox__puce[aria-current='true'] { width: 40px; background: var(--lsx-1); }
.lightbox__puce:hover { background: var(--c-accent); }

/* --- Variante claire du diaporama ---
   Deux fonds sont disponibles. Par défaut, la paroi sombre ; avec
   class="lightbox lightbox--clair" sur le <dialog>, le papier clair du
   lecteur vidéo (--modal-*), légende et boutons passant au brun. */
.lightbox--clair {
  background:
    linear-gradient(rgb(226 217 197 / var(--modal-voile)),
                    rgb(226 217 197 / var(--modal-voile))),
    var(--modal-matiere) center / cover no-repeat,
    var(--modal-base);
}

.lightbox--clair .lightbox__figure img {
  box-shadow: 0 34px 90px -22px rgba(38, 28, 18, 0.62),
              0 0 0 1px rgba(58, 45, 30, 0.14);
}

.lightbox--clair .lightbox__legende { color: #3A2D1E; }

.lightbox--clair .lightbox__btn {
  border-color: rgba(58, 45, 30, 0.3);
  background: rgba(255, 252, 245, 0.72);
  color: #3A2D1E;
}

.lightbox--clair .lightbox__btn:hover {
  border-color: var(--lsx-3);
  background: #FFFCF5;
  color: var(--lsx-3);
}

.lightbox--clair .lightbox__puce { background: rgba(58, 45, 30, 0.25); }
.lightbox--clair .lightbox__puce[aria-current='true'] { background: var(--lsx-1); }
.lightbox--clair .lightbox__puce:hover { background: var(--lsx-3); }

@media (max-width: 700px) {
  .lightbox__btn--prev { left: var(--s-3); }
  .lightbox__btn--next { right: var(--s-3); }
  .lightbox__figure img { max-height: 62vh; }
}

/* Mention « à compléter » des pages légales : un encart qui se voit, pour
   que personne ne publie le site en laissant ces trous. Il disparaîtra avec
   les informations manquantes. */
.a-completer {
  margin-top: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border-left: 3px solid var(--c-accent);
  background: rgb(212 97 15 / 0.08);
  border-radius: 0 var(--radius-s) var(--radius-s) 0;
  font-size: var(--t-small);
  color: var(--c-bone-2);
}

.a-completer strong { color: var(--c-accent); }

/* Objet photographié debout sur fond noir : on le montre entier plutôt que
   de le rogner au format des autres figures, et on borne sa hauteur pour
   qu'il ne domine pas la page. Le fond de la photo rejoint celui du site. */
.figure--objet img {
  display: block;
  width: auto;
  max-width: 100%;
  max-height: 540px;
  margin-inline: auto;
}

.figure figcaption {
  margin-top: var(--s-3);
  font-size: var(--t-micro);
  font-style: italic;
  line-height: 1.45;
  color: var(--c-text-muted);
}

.split { display: grid; gap: clamp(var(--s-6), 5vw, var(--s-9)); align-items: center; }

/* En une seule colonne, l'image passait avant le texte qu'elle illustre :
   on la voyait annoncer une section dont le titre n'était pas encore lu, et
   elle semblait appartenir au bloc précédent. Elle suit donc le texte tant
   qu'il n'y a qu'une colonne, et retrouve sa place dès que la mise en page se
   dédouble — là, le côte à côte dit la paire tout seul. */
.split__media { order: 2; }

@media (min-width: 960px) {
  .split { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .split__media { order: 0; }
  .split--reverse .split__media { order: 2; }
}

.split__media img { width: 100%; border-radius: var(--radius); }

/* Un bloc de prose qui n'a plus d'image à côté de lui : sans plafond, la ligne
   s'étirerait sur toute la largeur du conteneur et deviendrait pénible à
   suivre. La mesure reste celle du reste du site. */
.prose--seule { max-width: 68ch; }


/* =========================================================================
   11. PIED DE PAGE
   ========================================================================= */

/* --- Pied de page sur papier ---
   Le parcours sombre se referme sur une page de papier. Outre la respiration
   qu'il donne en fin de lecture, ce fond rend au logotype son usage
   d'origine : la charte le veut en couleur sur fond clair, il n'y a donc
   plus d'exception à faire valoir ici.

   Comme pour .section--papier, ce sont les RÔLES de couleur qui basculent :
   les listes, adresses, filets et pictos suivent sans être restylés un à un. */

.footer {
  --papier-fond:    #E4DAC5;
  /* 13.jpg — l'œil de l'animal. Plus sombre que le paysage (luminosité
     moyenne 153 contre 200), il demande une opacité plus basse pour ne pas
     assombrir le papier ni gêner la lecture. */
  --papier-matiere: url('../img/matieres/opt/13.jpg');
  --papier-opacite: 0.30;

  --c-text:         #3A2D1E;
  --c-text-muted:   #6B5A44;
  --c-accent:       var(--lsx-5);
  --c-bone:         #2E2416;
  --c-bone-2:       #4A3B28;
  --c-bone-3:       #6B5A44;
  --c-border:       rgba(58, 45, 30, 0.22);
  --c-border-soft:  rgba(58, 45, 30, 0.13);

  position: relative;
  isolation: isolate;
  background-color: var(--papier-fond);
  color: var(--c-text);
  border-top: 1px solid rgba(58, 45, 30, 0.2);
  padding-block: var(--section-y-s) var(--s-6);
}

.footer__grid { display: grid; gap: var(--s-7); }

/* Quatre colonnes : identité, Explorer, Contact, puis la brochure.
   La dernière est dimensionnée par son contenu (« auto ») : la couverture a
   une largeur fixe, il serait vain de lui donner une part de fraction. */
@media (min-width: 860px) { .footer__grid { grid-template-columns: 1.4fr 1fr 1.2fr auto; } }

.footer__title {
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: #2E2416;          /* brun profond — 12,4:1 sur le papier */
  margin-bottom: var(--s-4);
}

/* Logo en première colonne du pied de page. Comme dans l'en-tête, il respecte
   la longueur minimale de 200 px et sa zone de protection (49 % de sa hauteur,
   soit environ 27 px), ici assurée par la marge basse. */
.footer__logo {
  margin: 0 0 calc(var(--logo-w) / 3.666 * 0.49);
  line-height: 0;
}

.footer__logo img {
  width: var(--logo-w);
  height: auto;
}

/* Interlignage resserré : ces listes sont courtes et se lisent d'un bloc.
   L'interligne de lecture du corps de texte (1,62) les délavait. */
.footer__list > li + li { margin-top: var(--s-2); }

.footer__list a {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  font-size: var(--t-small);
  line-height: 1.35;
  color: var(--c-bone-2);
  transition: color var(--dur) var(--ease);
}

.footer__list a:hover { color: var(--lsx-3); }


/* --- Picto de menu : trois chevrons qui se rassemblent -------------------
   Reprise du principe du logotype, dont chaque lettre est faite de traits
   parallèles déclinés dans les couleurs de la charte. Au repos les trois
   chevrons sont décalés ; au survol ils convergent en un seul. */

.chev {
  width: 18px;
  height: 12px;
  flex-shrink: 0;
  overflow: visible;
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.chev path {
  transform-box: view-box;
  transition: transform 0.45s var(--ease-out), opacity 0.45s var(--ease-out);
}

/* Le premier chevron mène la marche, les deux autres le suivent en retrait
   et en couleurs plus profondes — comme les traits du logo. */
.chev path:nth-child(1) { stroke: var(--lsx-3); transform: translateX(8px); }
.chev path:nth-child(2) { stroke: var(--lsx-5); transform: translateX(4px); opacity: 0.8; }
.chev path:nth-child(3) { stroke: var(--lsx-6); transform: translateX(0);   opacity: 0.55; }

/* Au survol, les trois se superposent en tête : le faisceau se rassemble. */
.footer__list a:hover .chev path,
.footer__list a:focus-visible .chev path { transform: translateX(8px); opacity: 1; }

.footer__list a:hover .chev path:nth-child(2) { stroke: var(--lsx-3); }
.footer__list a:hover .chev path:nth-child(3) { stroke: var(--lsx-3); }

@media (prefers-reduced-motion: reduce) {
  .chev path { transition: none; }
}


/* --- Pictos de contact : courriel, téléphone, LinkedIn -------------------
   Même trait fin que le picto de menu, mais figuratifs : un seul tracé, un
   triplement les rendrait illisibles à cette taille. Ils s'allument à
   l'orange au survol, comme les chevrons se rassemblent. */

.ico {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  fill: none;
  stroke: var(--c-bone-3);
  stroke-width: 1.35;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke var(--dur) var(--ease);
}

.footer__list a:hover .ico,
.footer__list a:focus-visible .ico { stroke: var(--lsx-3); }

.footer address { font-style: normal; font-size: var(--t-small); line-height: 1.6; color: var(--c-bone-3); }

/* --- Brochure : la couverture en appel au téléchargement -----------------
   La couverture du PDF est sombre : sur le papier clair du pied de page,
   elle fait tache d'encre et attire l'œil sans qu'on ait à hausser le ton.
   Le lien enveloppe l'image et le libellé : une seule cible, un seul arrêt
   au clavier. */

.brochure {
  display: grid;
  gap: var(--s-3);
  justify-items: start;
  width: max-content;
}

.brochure__couv {
  display: block;
  width: var(--brochure-w);
  height: auto;
  border-radius: 2px;
  box-shadow: 0 10px 26px -10px rgba(30, 22, 12, 0.55),
              0 0 0 1px rgba(58, 45, 30, 0.18);
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}

.brochure__action {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-small);
  line-height: 1.35;
  font-weight: 700;
  color: #2E2416;
  transition: color var(--dur) var(--ease);
}

.brochure__meta {
  font-size: var(--t-micro);
  line-height: 1.35;
  color: var(--c-bone-3);
}

/* Au survol, la couverture se soulève légèrement — le geste du document
   qu'on prend sur une table, pas un effet d'interface. */
.brochure:hover .brochure__couv,
.brochure:focus-visible .brochure__couv {
  transform: translateY(-3px);
  box-shadow: 0 16px 34px -10px rgba(30, 22, 12, 0.62),
              0 0 0 1px rgba(58, 45, 30, 0.28);
}

.brochure:hover .brochure__action,
.brochure:focus-visible .brochure__action { color: var(--lsx-3); }

.brochure:hover .ico,
.brochure:focus-visible .ico { stroke: var(--lsx-3); }

@media (prefers-reduced-motion: reduce) {
  .brochure__couv { transition: none; }
  .brochure:hover .brochure__couv { transform: none; }
}

/* La raison sociale ouvre le bloc d'adresse : elle porte le même gras et le
   même brun profond que les intitulés de colonnes, dont elle tient lieu ici.
   Les lignes de voie et de ville restent en retrait. */
.footer__raison {
  font-weight: 700;
  color: #2E2416;   /* 12,4:1 sur le papier */
}

/* Logos institutionnels — fond blanc requis par la plupart des chartes d'État */
.partners { margin-top: var(--s-8); padding-top: var(--s-6); border-top: 1px solid var(--c-border-soft); }

.partners__row {
  display: flex;
  flex-wrap: wrap;
  /* Répartition régulière d'un bord à l'autre : les logos occupent toute la
     largeur du bandeau au lieu de se masser au centre.
     La marge blanche est la même sur les quatre côtés : le bandeau se lit
     comme un cadre, et les logos d'extrémité ne butent plus sur la bordure. */
  justify-content: space-between;
  align-items: center;
  gap: var(--s-4) var(--s-3);
  background: #FFFFFF;
  padding: var(--bandeau-marge);
  border: 1px solid rgba(58, 45, 30, 0.12);
  border-radius: var(--radius);
}

/* En dessous, la répartition d'un bord à l'autre creuserait des trous :
   on recentre et on laisse les logos passer à la ligne. */
@media (max-width: 900px) {
  .partners__row {
    justify-content: center;
    gap: var(--s-5) var(--s-6);
  }
}

/* La hauteur de référence est corrigée logo par logo, via --echelle posée
   dans le balisage : à hauteur strictement égale, un logo large et bas
   paraît écrasé quand un logo carré paraît démesuré. */
.partners__row img {
  height: calc(clamp(30px, 3.6vw, 46px) * var(--echelle, 1));
  width: auto;
  flex-shrink: 0;
}

/* Un logo peut porter un lien. L'ancre doit alors épouser l'image : en
   display inline elle traîne l'interligne derrière elle, et le logo se
   désaligne de ses voisins d'un ou deux pixels. */
.partners__row a {
  display: inline-flex;
  flex-shrink: 0;
  border-radius: 2px;
  transition: opacity var(--dur) var(--ease);
}

.partners__row a:hover { opacity: 0.72; }

.footer__bottom {
  margin-top: var(--s-6);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-border-soft);
  display: grid;
  gap: var(--s-3) var(--s-5);
  align-items: center;
  font-size: var(--t-micro);
  color: var(--c-text-muted);
  text-align: center;
}

@media (min-width: 900px) {
  .footer__bottom {
    grid-template-columns: 1fr auto 1fr;
  }
  .footer__bottom-gauche { text-align: left; }
  .footer__signature     { text-align: right; }
}

.footer__bottom a:hover { color: var(--lsx-3); }

/* --- Signature de l'agence ---
   Troisième colonne de la barre du bas, alignée à droite. Elle partage le
   corps des mentions légales mais reste en retrait par sa couleur. */
.footer__signature {
  letter-spacing: 0.04em;
  color: var(--c-text-muted);
}

.footer__signature a {
  color: var(--c-accent);
  border-bottom: 1px solid transparent;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.footer__signature a:hover {
  color: var(--lsx-3);
  border-bottom-color: var(--lsx-3);
}


/* =========================================================================
   12. APPARITIONS AU DÉFILEMENT
   ========================================================================= */

/* Le masquage est conditionné à la classe « js », posée dans le <head> par un
   script inline synchrone. Sans elle — JavaScript coupé, script bloqué par un
   filtre, réseau qui lâche — le contenu s'affiche normalement au lieu de
   rester invisible. C'est du contenu, il ne doit jamais dépendre d'un script
   pour être lu.

   Le script du <head> retire aussi la classe au bout de trois secondes si
   site.js n'a pas signalé son démarrage : la page se répare d'elle-même. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js [data-reveal].is-visible { opacity: 1; transform: none; }


/* =========================================================================
   13. ACCESSIBILITÉ — mouvement réduit
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .js [data-reveal] { opacity: 1; transform: none; }

  /* Les vidéos de fond cèdent la place à leur image de repli */
  .hero__media video,
  .page-hero__media video,
  .media-band__media video { display: none; }
}


/* =========================================================================
   PAGES LÉGALES — mentions légales, confidentialité
   ========================================================================= */

/* Ces pages ne sont pas des pages d'édition : on ne les parcourt pas, on y
   cherche un renseignement précis. Leurs titres gardaient pourtant l'échelle
   des pages de contenu — 37 px pour le titre, 29 px pour les intertitres, sur
   un texte à 19,5. Un intertitre une fois et demie plus gros que ce qu'il
   annonce écrase la réponse qu'on est venu lire. L'échelle est resserrée ; la
   hiérarchie reste lisible, chaque niveau gardant son écart au précédent.

   Ces règles vivent ici et non dans pages.css : les pages légales ne chargent
   que tokens.css et main.css. C'est aussi là qu'est .a-completer. */
.section--legal h1 { font-size: clamp(1.5rem, 2.6vw, 2rem); }

.section--legal .prose h2 {
  font-size: clamp(1.18rem, 1.7vw, 1.4rem);
  margin-top: 2.4em;
}

.section--legal .prose h3 {
  font-size: clamp(0.95rem, 1.2vw, 1.02rem);
  margin-top: 1.8em;
}

/* Le chapô suivait le titre dans sa chute : il redescend d'autant. */
.section--legal .prose .lead { font-size: var(--t-body); }
