/* composants.css — composants partagés de Villa Vida, à la charte graphique v1.0 (noir, or, blanc ; les notes
   seulement dans le logo). HTML exact à copier : STYLEGUIDE.md.
   Règles :
   - le style de BASE de chaque composant est sa frame finale (mouvement réduit, navigateur sans scroll-driven) ;
   - toute animation scroll-driven est écrite en forme longue, dans @supports (animation-timeline: view())
     ET @media (prefers-reduced-motion: no-preference) ; repli IntersectionObserver par main.js (html.sans-sd) ;
   - chaque lien, bouton et champ répond au survol, au focus clavier et à l'appui. */

/* =================================================================== 1. BANDEAU MAQUETTE */
.bandeau {
  position: relative; z-index: calc(var(--z-barre) + 1);
  min-height: var(--bandeau-h);
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: .25rem .9rem;
  padding: 2px var(--marge);
  background: var(--noir-2); color: var(--texte-2);
  border-bottom: 1px solid var(--ligne);
  font-size: var(--t-mini); font-weight: 600; line-height: 1.2; letter-spacing: .04em;
  text-align: center;
}
.bandeau p { margin: 0; }
.bandeau-reperer {
  display: inline-flex; align-items: center; gap: .4em; min-height: 24px;
  padding: 0 .5em; border: 0; border-radius: 3px;
  background: transparent; color: var(--texte);
  font-size: var(--t-mini); font-weight: 700; letter-spacing: .04em;
  text-decoration: underline dotted 1px; text-decoration-color: var(--or); text-underline-offset: .25em;
  transition: background-color 200ms var(--elan), color 200ms var(--elan);
}
.bandeau-reperer:hover { background: var(--or); color: var(--noir); text-decoration: none; }
.bandeau-reperer:active { translate: 0 1px; }
.bandeau-reperer[aria-pressed="true"] { background: var(--or); color: var(--noir); text-decoration: none; }
.bandeau-n { display: inline-block; min-width: 2.2em; padding: .1em .45em; border-radius: 999px; background: var(--or); color: var(--noir); text-decoration: none; }
.bandeau-reperer[aria-pressed="true"] .bandeau-n { background: var(--noir); color: var(--texte); }
.bandeau-reperer { white-space: nowrap; }
/* zone tactile (11.10.2026, audit §20) : 44 px de haut sous le doigt, la bande garde ses 28 px (marge négative) */
@media not all and (min-width: 900px), (pointer: coarse) {
  .bandeau-reperer { min-height: 44px; margin-block: -10px; }
}
@media (max-width: 480px) {
  .bandeau { flex-wrap: nowrap; gap: .5rem; font-size: .6875rem; letter-spacing: .02em; }
  .bandeau p { white-space: nowrap; }
  .bandeau-option, .bandeau-mot { display: none; }
}

/* =================================================================== 2. MARQUE « À CONFIRMER » */
mark.ac {
  display: inline-block;
  margin-inline: .2em; padding: .18em .5em .12em;
  border-radius: 3px;
  background: var(--or-clair); color: var(--noir);
  font-family: var(--f-texte); font-size: var(--t-mini); font-weight: 700; font-style: normal;
  font-variation-settings: normal;
  line-height: 1.15; letter-spacing: .05em; text-transform: uppercase; vertical-align: .25em;
  white-space: nowrap;
}
.fond-papier mark.ac, .billet mark.ac, .cb-papier mark.ac { background: var(--noir); color: var(--texte); }
/* mode « repérer » (bouton du bandeau) : toutes les marques et propositions sautent aux yeux */
.reperer-ac mark.ac { outline: 3px dashed var(--or-clair); outline-offset: 3px; }
.reperer-ac [data-ac] { outline: 2px dashed currentColor; outline-offset: 6px; }
.reperer-ac [data-ac]::after {
  content: "proposition de l'agence · à confirmer";
  display: block; width: max-content; margin-top: .6em; padding: .2em .6em;
  background: var(--or-clair); color: var(--noir);
  font: 700 var(--t-mini)/1.2 var(--f-texte); letter-spacing: .05em; text-transform: uppercase;
  font-variation-settings: normal;
}

/* =================================================================== 3. BOUTONS ET LIENS-ACTIONS (charte §13)
   Principal : or plein, texte noir. Secondaire : contour or. Sur fond clair : noir plein. Anybody 800, largeur 70. */
.bouton {
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center; gap: .55em;
  min-height: 48px; padding: .75em 1.5em;
  border: 2px solid var(--or); border-radius: 999px;
  background: var(--or); color: var(--noir);
  font-family: var(--f-display); font-size: var(--t-petit); font-weight: 800; font-variation-settings: 'wdth' 70, 'wght' 800;
  line-height: 1.1; letter-spacing: .04em; text-transform: uppercase;
  text-decoration: none; text-align: center;
  transition: translate 160ms var(--elan), background-color 200ms var(--elan), border-color 200ms var(--elan), color 200ms var(--elan);
}
.bouton:hover { text-decoration: none; background: var(--or-clair); border-color: var(--or-clair); }
.bouton:active { translate: 0 2px; }
.bouton .fleche { flex: none; width: 1.25em; transition: translate 300ms var(--prise); }
.bouton:hover .fleche, .bouton:focus-visible .fleche { translate: .3em 0; }
.bouton--papier { background: var(--noir); border-color: var(--noir); color: var(--blanc); }   /* sur fond clair : noir plein */
.bouton--papier:hover { background: var(--noir-3); border-color: var(--noir-3); }
.bouton--fil { background: transparent; color: var(--or); }                                  /* secondaire : contour or */
.bouton--fil:hover { background: transparent; border-color: var(--or-clair); color: var(--or-clair); }
.bouton[aria-disabled="true"] { opacity: .75; cursor: not-allowed; }

/* lien souligné qui « fait un pas » */
.lien-pas {
  display: inline-flex; align-items: center; gap: .4em;
  font-weight: 700; text-decoration: underline 2px var(--or); text-underline-offset: .3em;
  transition: gap 300ms var(--prise);
}
.lien-pas:hover, .lien-pas:focus-visible { gap: .8em; }
.lien-pas:active { translate: 0 1px; }
.lien-pas .fleche { width: 1em; }
/* zones tactiles (11.10.2026, audit §20) : au téléphone (et sous un doigt), un lien isolé fait 44 px de haut au moins.
   La zone s'agrandit sans rien déplacer : padding-block de (44 px − 1 ligne) / 2, rendu par une marge négative égale
   (la boîte de marge garde la hauteur d'une ligne ; le texte reste à sa place). Sans l'unité lh : rien ne change.
   Une règle de page qui pose son propre padding-block sur un .lien-pas reste prioritaire (voir NOTES-global). */
@media not all and (min-width: 900px), (pointer: coarse) {
  .lien-pas {
    padding-block: max(0px, calc((44px - 1lh) / 2));
    margin-block: min(0px, calc((1lh - 44px) / 2));
  }
}

.fleche { display: inline-block; width: 1.2em; height: .6em; flex: none; overflow: visible; vertical-align: middle; }
.fleche-bas { display: inline-block; width: .7em; height: .95em; flex: none; overflow: visible; }
/* ↗ : un lien qui quitte le site (la billetterie Weezevent) ; la flèche du sprite, tournée d'un huitième de tour.
   Au survol, elle part en diagonale. (Les polices n'ont pas le glyphe ↗.) */
.fleche-sortie { width: .95em; rotate: -45deg; }
.bouton .fleche-sortie { width: 1em; }
:is(.bouton, .lien-pas):hover .fleche-sortie, :is(.bouton, .lien-pas):focus-visible .fleche-sortie { translate: .15em -.15em; }

/* =================================================================== 4. BARRE + « JE PARTICIPE »
   Noir, filet or en bas (il se déroule avec la lecture). Le logo, seul, dans son disque blanc cerclé d'or, à 96 px
   (charte §05 : taille minimale du logo en disque, « la taille de l'en-tête du site ») ; jamais de nom écrit à côté.
   12.10.2026, décision Yann : au téléphone (tokens.css), la barre est compacte, 64 px, disque de 52 px ; « Menu » et
   « Je participe » gardent leurs 44 px de haut (10 px de noir au-dessus et au-dessous). La place gagnée va au grand logo
   de l'accueil. Rien d'autre ne change : mêmes éléments, même ordre, mêmes couleurs. */
.barre {
  position: sticky; top: 0; z-index: var(--z-barre);
  height: var(--barre-h);
  display: flex; align-items: center; gap: .5rem;
  padding-inline: var(--marge);
  background: var(--noir);
  color: var(--texte);
  isolation: isolate;
}
.barre::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; pointer-events: none;
  background: var(--ligne);
}
/* le filet de la journée : il se déroule avec la lecture (scroll-driven, forme longue ; frame finale = déroulé) */
.barre::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--or);
  transform-origin: 0 50%;
  pointer-events: none;
}
.barre-logo {
  display: block; flex: none;
  width: var(--disque-barre); height: var(--disque-barre);
  border-radius: 50%;
  text-decoration: none;
  transition: scale 200ms var(--elan);
}
.barre-logo:active { scale: .97; }
.barre-logo:focus-visible { outline-offset: 3px; border-radius: 50%; }

/* ------------------------------------------------------------------ le logo en disque (charte §03, §10)
   Disque blanc, filet or de 1/60 du diamètre ; le logo au centre, intact (ni pivoté, ni recoloré, ni effet).
   .disque-cadre fixe le diamètre (container-type : le filet se calcule sur lui) ; .vv-logo = calques animables (logo.js) */
.disque-cadre { container-type: inline-size; position: relative; display: block; width: 100%; aspect-ratio: 1; }
.disque picture { display: contents; }
.disque {
  position: absolute; inset: 0;
  border-radius: 50%;
  background: var(--blanc);
  border: max(1px, calc(100cqi / 60)) solid var(--or);
}
.disque .disque-logo, .disque > .vv-logo { position: absolute; inset: 5%; width: 90%; height: 90%; }
.disque-logo { display: block; clip-path: circle(53.7% at 50% 50%); }   /* le carré blanc du fichier, découpé au cercle intérieur (rayon 0,5 − 1/60 du disque, sur 90 %) */
.disque > .logo-hote { position: absolute; inset: 5%; }   /* hôte des calques animables (logo.js) ; le statique d'abord */
.logo-hote picture { display: contents; }
.disque .logo-hote .disque-logo { inset: 0; width: 100%; height: 100%; }
.vv-logo { container-type: inline-size; }
.vv-scene { position: absolute; inset: 0; contain: layout style; }   /* insérer ou animer les calques ne relance pas la mise en page de la page */
.vv-en-attente .vv-note { opacity: 0; }   /* fleurir : notes cachées le temps de créer leurs animations (< 100 ms) */
.vv-arbre, .vv-poussiere, .vv-note, .vv-lettre { position: absolute; display: block; max-width: none; background-repeat: no-repeat; }
.vv-poussiere { inset: 0; width: 100%; height: 100%; }
.vv-grappe { position: absolute; will-change: transform; }

/* « Menu ↓ » (ex-« La journée » ; la pastille horaire est retirée le 06.10.2026) */
.barre-journee {
  position: absolute; left: var(--part-suit); top: 50%;
  translate: -50% -50%;
  display: inline-flex; align-items: center; gap: .45em;
  min-height: 44px; padding: 0 .85em;
  border: 0; border-radius: 999px;
  background: transparent; color: var(--texte);
  font-size: .9375rem; font-weight: 700; letter-spacing: -.005em; white-space: nowrap;
  transition: background-color 220ms var(--elan), color 220ms var(--elan);
}
.barre-journee:hover, .barre-journee[aria-expanded="true"] { background: var(--noir-3); color: var(--or-clair); }
.barre-journee:active { scale: .97; }
.barre-journee .fleche-bas { width: .7em; height: .9em; transition: translate 300ms var(--prise); }
.barre-journee:hover .fleche-bas { translate: 0 .15em; }
/* « Je participe » : toujours dans la barre, à droite, dès t = 0. Bouton principal : or plein, texte noir. */
.cta-participe {
  position: relative; isolation: isolate;
  margin-left: auto;
  display: inline-flex; flex-direction: column; justify-content: center; align-items: center;
  min-height: 44px; padding: .3rem 1rem;
  border-radius: 999px;
  background: var(--or); color: var(--noir);
  font-family: var(--f-display); font-size: .875rem; font-weight: 800; font-variation-settings: 'wdth' 70, 'wght' 800;
  line-height: 1.05; letter-spacing: .04em; text-transform: uppercase; white-space: nowrap;
  text-decoration: none;
  transition: translate 160ms var(--elan), background-color 200ms var(--elan);
}
.cta-participe:hover { text-decoration: none; background: var(--or-clair); }
.cta-participe:active { translate: 0 2px; }

/* téléphone : le bouton suit le logo pour laisser sa place à « Je participe » */
@media (max-width: 599px) {
  .barre-journee { position: static; translate: none; padding: 0 .45em; gap: .3em; font-size: .875rem; }
}
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .barre::after {
      animation-name: fil-journee; animation-duration: 1ms; animation-timing-function: linear; animation-fill-mode: both;
      animation-timeline: scroll(root block);
    }
  }
}
@keyframes fil-journee { from { scale: 0 1; } }
@media (min-width: 900px) {
  .barre { gap: 1.5rem; }
  .barre-journee { font-size: 1rem; padding: 0 1.1em; }
  .cta-participe { flex-direction: row; gap: .45em; min-height: 48px; padding: 0 1.6rem; font-size: 1rem; }
}
/* écran très bas (≤ 30 rem : zoom 400–500 % au bureau, téléphone couché) : la barre (108 px, ou 64 px au téléphone) ne
   colle plus, elle mangerait l'écran. 11.10.2026 : elle colle de nouveau sur un écran étroit mais haut (320 px de large) : la barre
   « headroom » s'y range au défilement. */
@media (max-height: 30rem) {
  .barre { position: relative; }
}
/* 11.10.2026 : le focus dans la barre collante ne fait plus défiler la page. Collée en haut, la barre est dans la bande du
   scroll-padding-top (barre + 1 rem) : Chrome la croyait cachée et faisait défiler la page vers le haut pour la montrer,
   d'environ un demi-écran à chaque focus (logo, Menu, « Je participe »). Sa zone de défilement (scroll-margin) descend
   donc jusqu'au bas de l'écran : elle couvre toute la zone visible, le navigateur la juge visible et ne bouge pas.
   Seulement quand la barre colle : sur un écran très bas, elle défile avec la page et le focus doit la ramener. */
@media not all and (max-height: 30rem) {
  .barre :is(a, button) { scroll-margin-bottom: calc(100lvh + var(--barre-h)); }
}
/* ------------------------------------------------------------------ la barre « headroom » au téléphone (11.10.2026, audit P2-14)
   Sous 900 px, barre.js (chargé par main.js) pose html.barre-rangee au défilement vers le bas, une fois la barre
   dépassée, et la retire au premier geste vers le haut (seuil de 12 px). Un translate seul (compositeur), 250 ms ;
   instantané en mouvement réduit (base.css). Rien ne bouge dans la mise en page : la barre garde sa place dans le flux.
   Elle reste là quand le Menu est ouvert et quand le focus clavier est dedans (et barre.js la garde en haut et en bas de
   page, pendant l'envol de l'accueil et après un saut d'ancre). Au bureau, rien ne change. */
@media not all and (min-width: 900px) {
  .barre { transition: translate 250ms var(--elan); }
  .barre-rangee .barre { translate: 0 -100%; }
  .journee-ouverte .barre { translate: none; }
}
@media not all and (min-width: 900px) {
  /* règle à part (sans :has(), seule elle tombe). Sans transition : la barre est là dès le focus, et le navigateur
     ne fait pas défiler la page pour montrer un élément qu'il croirait encore hors de l'écran. */
  .barre-rangee .barre:has(:focus-visible) { translate: none; transition: none; }
}

/* =================================================================== 5. LA JOURNÉE : la page se fend sur la couture, les pas apparaissent entre les moitiés */
.journee {
  position: fixed; inset: 0; z-index: var(--z-journee);
  width: 100%; height: 100%; max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0;
  overflow: auto; overscroll-behavior: contain;
  background: var(--fond-couture);
  color: var(--texte);
  clip-path: inset(0 0 0 0);
  transition: clip-path calc(var(--temps) * 1.2) var(--elan), display calc(var(--temps) * 1.2) allow-discrete, overlay calc(var(--temps) * 1.2) allow-discrete;
}
.journee::before {
  content: ""; position: fixed; inset: 0; pointer-events: none;
  background-image: var(--grain); background-size: var(--grain-taille) var(--grain-taille); opacity: var(--grain-opacite);
}
.journee::backdrop { background: transparent; }
@supports not selector(:popover-open) {
  .journee { display: none; }
  .journee.est-ouvert { display: block; }
}
.journee:not(:popover-open) { clip-path: inset(0 calc(100% - var(--part-suit)) 0 var(--part-suit)); }
@starting-style {
  .journee:popover-open { clip-path: inset(0 calc(100% - var(--part-suit)) 0 var(--part-suit)); }
}
.journee-cadre {
  position: relative;
  min-height: 100%;
  display: grid; align-content: center; gap: clamp(1.5rem, 4vh, 3rem);
  padding: calc(var(--barre-h) + 1rem) 0 3rem;
}
.journee-titre {
  display: grid; grid-template-columns: var(--part-suit) 1fr;
  font-family: var(--f-display); font-size: clamp(3rem, 1.6rem + calc(5 * var(--vw)), 6.5rem); line-height: .9;
}
.journee-titre .duo-q { grid-column: 1 / -1; justify-self: center; font-weight: 200; font-variation-settings: var(--delie); }
.journee-titre .duo-r { grid-column: 2; padding-left: .25em; font-weight: 900; font-variation-settings: var(--plein); }
.journee-titre .duo-r:only-child { grid-column: 1 / -1; justify-self: center; padding-left: 0; color: var(--or); }   /* « Menu », seul */
.journee-pas { display: grid; gap: .1rem; counter-reset: pas; }
.journee-pas li { --i: 0; }
.journee-pas a {
  position: relative;
  display: grid; grid-template-columns: var(--part-suit) 1fr; align-items: baseline;
  min-height: 48px; padding-block: .3rem;
  color: inherit; text-decoration: none;
}
.journee-pas .pas-g, .journee-pas .pas-d {
  font-family: var(--f-display); font-size: clamp(1.75rem, 1rem + calc(3.4 * var(--vw)), 4.25rem); line-height: 1;
  transition: translate 420ms var(--prise), opacity 300ms var(--elan);
}
.journee-pas .pas-g {
  justify-self: end; padding-right: clamp(.8rem, calc(2.5 * var(--vw)), 2rem);
  font-weight: 900; font-variation-settings: var(--plein); font-variant-numeric: tabular-nums;
}
.journee-pas .pas-d {
  padding-left: clamp(.8rem, calc(2.5 * var(--vw)), 2rem);
  font-weight: 300; font-variation-settings: 'wdth' 125, 'wght' 300;
}
/* le petit y qui se pose sur la couture quand on choisit un pas */
.journee-pas a::after {
  content: "y";
  position: absolute; left: var(--part-suit); top: 50%;
  width: 1.6em; height: 1.6em; margin: -.8em 0 0 -.8em;
  display: grid; place-items: center;
  border-radius: 50%; background: var(--or); color: var(--noir);
  font: 900 1rem/1 var(--f-display); font-variation-settings: var(--noeud);
  scale: 0; transition: scale 300ms var(--prise);
}
.journee-pas a:hover::after, .journee-pas a:focus-visible::after { scale: 1; }
.journee-pas a:hover .pas-g, .journee-pas a:focus-visible .pas-g { translate: -.35em 0; }
.journee-pas a:hover .pas-d, .journee-pas a:focus-visible .pas-d { translate: .35em 0; }
.journee-pas a:active { translate: 0 2px; }
.journee-pas a:focus-visible { outline-offset: -3px; }
.journee-pas a[aria-current="page"] .pas-d { font-weight: 700; font-variation-settings: 'wdth' 125, 'wght' 700; }
/* téléphone (10.10.2026, audit P1-2) : en délié large (wdth 125), « L’association » sortait de l'écran de 320 à 480 px
   (bord droit à 405 px pour 375). Sous 36 rem, le délié passe à la largeur normale (wdth 100) et le pas de la page
   courante, en gras, à wdth 80 (le gras est plus large) : la ligne la plus longue finit à ≥ 24 px du bord à 320, 375
   et 414 px. */
@media (max-width: 36rem) {
  .journee-pas .pas-d { font-variation-settings: 'wdth' 100, 'wght' 300; padding-right: var(--marge); }   /* un libellé trop long passe à la ligne avant la marge */
  .journee-pas a[aria-current="page"] .pas-d { font-variation-settings: 'wdth' 80, 'wght' 700; }
}
/* entrée des pas : celui qui guide (à droite) d'abord, celui qui suit un temps plus tard */
.journee .pas-d { transition-delay: calc(140ms + var(--i) * 45ms); }
.journee .pas-g { transition-delay: calc(140ms + var(--temps) * .5 + var(--i) * 45ms); }
.journee:not(:popover-open) .pas-d { translate: 1.5em 0; opacity: 0; }
.journee:not(:popover-open) .pas-g { translate: -1.5em 0; opacity: 0; }
@starting-style {
  .journee:popover-open .pas-d { translate: 1.5em 0; opacity: 0; }
  .journee:popover-open .pas-g { translate: -1.5em 0; opacity: 0; }
}
.journee-fermer {
  position: absolute; top: calc((var(--barre-h) - 44px) / 2); left: var(--part-suit); translate: -50% 0;
  display: inline-flex; align-items: center; gap: .45em; min-height: 44px; padding: 0 1em;
  border: 0; border-radius: 999px; background: var(--or); color: var(--noir);
  font-size: .9375rem; font-weight: 700;
  transition: scale 200ms var(--elan);
}
.journee-fermer:hover { scale: 1.04; }
.journee-fermer:active { scale: .97; }
.journee-fermer .fleche-bas { width: .7em; height: .9em; rotate: 180deg; }
.journee-pied {
  display: grid; grid-template-columns: var(--part-suit) 1fr;
  font-size: var(--t-petit);
}
.journee-pied > :first-child { justify-self: end; padding-right: clamp(.8rem, calc(2.5 * var(--vw)), 2rem); text-align: right; }
.journee-pied > :last-child { padding-left: clamp(.8rem, calc(2.5 * var(--vw)), 2rem); }
.journee-pied a { font-weight: 700; }

/* =================================================================== 6. DUO-TITRE : la question en délié, la réponse en plein */
.duo-titre {
  font-family: var(--f-display);
  font-size: var(--t-h2);
  line-height: .9;
  letter-spacing: 0;
}
.duo-titre .duo-q, .duo-titre .duo-r { display: block; }
.duo-q { font-weight: 200; font-variation-settings: var(--delie); }
.duo-r { font-weight: 900; font-variation-settings: var(--plein); color: var(--or); }   /* le plein en or (charte §09, §12 : « Winter ») */
:is(.billet, .fond-papier, .cb-papier) .duo-r { color: var(--or-profond); }
.duo-titre .duo-r { margin-top: .06em; }
/* l'axe en mouvement : ≤ 20 glyphes par titre (repeint sur le thread principal). Frame finale = resserré / ouvert. */
.duo-titre .axe-q { font-variation-settings: var(--delie-serre); }
.duo-titre .axe-r { font-variation-settings: var(--plein-ouvert); }
/* révélation masquée (data-revele) : chaque ligne monte derrière son masque */
.duo-titre[data-revele] .duo-q, .duo-titre[data-revele] .duo-r { overflow: clip; padding-block: .06em .12em; margin-block: -.06em -.12em; }
.duo-titre[data-revele] .duo-r { margin-top: 0; }
.duo-titre[data-revele] .ligne { display: block; }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .duo-titre .axe-q {
      animation-name: axe-resserre; animation-duration: 1ms; animation-timing-function: linear; animation-fill-mode: both;
      animation-timeline: view(); animation-range: entry 40% cover 55%;
    }
    .duo-titre .axe-r {
      animation-name: axe-ouvre; animation-duration: 1ms; animation-timing-function: linear; animation-fill-mode: both;
      animation-timeline: view(); animation-range: entry 50% cover 60%;
    }
    .duo-titre[data-revele] .ligne {
      animation-name: revele; animation-duration: 1ms; animation-timing-function: var(--elan); animation-fill-mode: both;
      animation-timeline: view(); animation-range: entry 0% entry 90%;
    }
    .duo-titre[data-revele] .duo-r .ligne { animation-range: entry 25% entry 100%; }
  }
}
@keyframes axe-resserre { from { font-variation-settings: var(--delie); } }
@keyframes axe-ouvre    { from { font-variation-settings: var(--plein); } }
@keyframes revele       { from { translate: 0 105%; } }
/* repli sans scroll-driven (main.js pose html.sans-sd et .vu au passage) */
.sans-sd .duo-titre[data-revele] .ligne { transition: translate 700ms var(--elan); }
.sans-sd .duo-titre[data-revele] .duo-r .ligne { transition-delay: var(--temps); }
.sans-sd .duo-titre[data-revele]:not(.vu) .ligne { translate: 0 105%; }
.sans-sd .duo-titre .axe-q, .sans-sd .duo-titre .axe-r { transition: font-variation-settings 900ms var(--elan) 200ms; }
.sans-sd .duo-titre:not(.vu, [data-axe-fige]) .axe-q { font-variation-settings: var(--delie); }
.sans-sd .duo-titre:not(.vu, [data-axe-fige]) .axe-r { font-variation-settings: var(--plein); }
/* sans reflux (main.js) : si le wdth animé fait changer les lignes d'un titre (le texte qui suit sauterait d'une ligne au
   défilement : layout shift), main.js réduit l'amplitude de l'axe jusqu'à ce que les lignes tiennent (data-axe-amplitude,
   en %) ; sous 20 %, l'axe reste sur sa frame finale (data-axe-fige). La révélation masquée, elle, continue. */
[data-axe-fige] :is(.axe-q, .axe-r) { animation-name: none !important; transition: none !important; }
/* téléphone (11.10.2026, P2 §12) : le duo h2 tient en deux lignes au total à 320 px (question ≤ 22 signes, réponse ≤ 12).
   La taille vient de --t-h2 (tokens.css) ; ici, les largeurs : une seule par moitié, au repos comme au défilement — la
   question en délié resserré (wdth 78 ; 72 sous 21,9 rem, §18), la réponse en plein 900 / 56 (la charte) ; la partie
   « axe » prend la largeur de sa moitié (inherit : une règle de page sur .duo-q, ex. .participe-titre, vaut pour toute
   la ligne). Les axes ne s'animent pas au téléphone : aucun titre ne change de largeur au défilement (CLS 0, même
   centré), aucune mise en page par image ; la révélation masquée (translate) reste. Pour main.js, ces titres n'ont pas
   d'axe animé : rien à mesurer. Repli sans scroll-driven (.sans-sd) : idem, aucune transition d'axe. */
@media (max-width: 599px) {
  h2.duo-titre { --delie: 'wdth' 78, 'wght' 200; --delie-serre: var(--delie); }   /* une règle de page qui lit --delie-serre suit */
  h2.duo-titre :is(.axe-q, .axe-r) { animation-name: none; transition: none; font-variation-settings: inherit; }
  .sans-sd h2.duo-titre:not(.vu, [data-axe-fige]) :is(.axe-q, .axe-r) { font-variation-settings: inherit; }
}

/* sur-titre (eyebrow) : petites capitales espacées, une hiérarchie réelle (édition, salle, heure) */
.sur-titre {
  display: block;
  font-family: var(--f-texte); font-size: var(--t-mini); font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; line-height: 1.3;
  color: var(--or);
}
:is(.billet, .fond-papier, .cb-papier) .sur-titre { color: var(--or-profond); }

/* =================================================================== 7. COLONNES NOIR-2 | NOIR, SÉPARÉES PAR LE FILET OR */
.colonnes {
  display: grid;
  grid-template-columns: var(--part-suit) var(--part-guide);
  background: var(--fond-couture);
}
.colonnes > * { min-width: 0; padding-block: var(--pas); }
.colonnes > :first-child { padding-left: var(--marge); padding-right: clamp(.75rem, calc(2.4 * var(--vw)), 2.75rem); }
.colonnes > :last-child  { padding-right: var(--marge); padding-left: clamp(.75rem, calc(2.4 * var(--vw)), 2.75rem); }
.colonnes--inverse { grid-template-columns: var(--part-guide) var(--part-suit); background: var(--fond-inverse); }
.colonnes--touche { background: var(--fond-touche); }
.colonnes--touche > :first-child { padding-right: clamp(.6rem, calc(1.6 * var(--vw)), 1.75rem); }
.colonnes--touche > :last-child { padding-left: clamp(.6rem, calc(1.6 * var(--vw)), 1.75rem); }
/* le contenu côté gauche s'appuie sur la couture */
.colonnes .vers-couture { text-align: right; justify-self: end; }
@media (max-width: 21.9rem) {
  .colonnes, .colonnes--inverse { grid-template-columns: 1fr; }
  .colonnes > :first-child, .colonnes > :last-child { padding-inline: var(--marge); }
  .colonnes .vers-couture { text-align: left; justify-self: start; }
}

/* =================================================================== 8. COUPLE COUPÉ « X y Y » (affiche, cartes) */
.couple-coupe {
  --part: var(--part-suit);
  --taille: var(--t-h3);
  --serre: .14em;
  position: relative;
  display: grid; grid-template-columns: var(--part) 1fr; align-items: baseline;
  color: inherit; text-decoration: none;
  font-family: var(--f-display); font-size: var(--taille); line-height: .92;
}
.couple-coupe .couple-x, .couple-coupe .couple-z {
  font-weight: 900; font-variation-settings: var(--plein); text-transform: uppercase; letter-spacing: .01em;
  transition: translate 520ms var(--prise);
}
.couple-coupe .couple-x { justify-self: end; padding-right: .62em; translate: calc(-1 * var(--serre)) 0; }
.couple-coupe .couple-z { justify-self: start; padding-left: .62em; translate: var(--serre) 0; }
.liste-couples { display: grid; gap: clamp(1.5rem, calc(4 * var(--vw)), 3.25rem); }
/* le nœud : le y (ou le « & » quand c'est ainsi publié) posé sur la couture */
.couple-coupe .couple-y {
  position: absolute; z-index: 1; left: var(--part); top: 0;
  width: 1.55em; height: 1.55em; margin-left: -.775em; margin-top: .02em;
  display: grid; place-items: center;
  border-radius: 50%; background: var(--or); color: var(--noir);
  font-weight: 900; font-variation-settings: var(--noeud); font-size: .62em; line-height: 1;
  text-transform: none;
  transition: scale 300ms var(--prise), rotate 520ms var(--prise);
}
.couple-coupe .couple-meta {
  grid-column: 1 / -1; display: grid; grid-template-columns: var(--part) 1fr; margin-top: .55rem;
  font-family: var(--f-texte); font-size: var(--t-petit); font-weight: 600; line-height: 1.3;
  text-transform: none; letter-spacing: 0;
}
.couple-coupe .couple-meta > :first-child { justify-self: end; padding-right: .9rem; text-align: right; }
.couple-coupe .couple-meta > :last-child { padding-left: .9rem; }
/* se recolle au survol, au focus, au toucher */
a.couple-coupe:hover .couple-x, a.couple-coupe:focus-visible .couple-x, .couple-coupe:active .couple-x { translate: .1em 0; }
a.couple-coupe:hover .couple-z, a.couple-coupe:focus-visible .couple-z, .couple-coupe:active .couple-z { translate: -.1em 0; }
a.couple-coupe:hover .couple-y, a.couple-coupe:focus-visible .couple-y { scale: 1.12; rotate: -10deg; }
a.couple-coupe:focus-visible { outline-offset: 8px; }
.couple-coupe--inverse { --part: var(--part-guide); }
.couple-coupe--grand { --taille: clamp(2.6rem, 1.2rem + calc(6.6 * var(--vw)), 8rem); }
.couple-coupe--moyen { --taille: clamp(2rem, 1rem + calc(4.2 * var(--vw)), 5.25rem); }
.couple-coupe--petit { --taille: clamp(1.6rem, 1rem + calc(2.4 * var(--vw)), 3.25rem); }
/* variante carte : deux demi-cartes noir-2 | noir qui épousent les prénoms */
.couple-coupe--carte .couple-x, .couple-coupe--carte .couple-z { padding-block: .22em .16em; }
.couple-coupe--carte .couple-x { background: var(--suit); padding-left: .45em; margin-right: 2px; }
.couple-coupe--carte .couple-z { background: var(--guide); padding-right: .45em; margin-left: 2px; }
.couple-coupe--carte .couple-y { top: .1em; }
.couple-coupe--carte .couple-meta { margin-top: .35rem; }

/* =================================================================== 9. PHOTO RÉELLE, EN COULEUR (charte §11)
   Les photos ne sont plus coupées ni teintées : la photo couleur seule (.photo-duo-couleur), au repos.
   Si un texte se pose un jour sur une photo : voile noir dégradé (--voile-photo) sous le texte, jamais de couleur.
   Les noms de classes sont gardés (data-recolle n'a plus d'effet). */
.photo-duo { --coupe: 50%; position: relative; }
.photo-duo-cadre {
  position: relative;
  aspect-ratio: var(--ratio, 4 / 3);
  overflow: clip;
}
.photo-duo-cadre > picture, .photo-duo-cadre > img { position: absolute; inset: 0; width: 100%; height: 100%; }
.photo-duo-cadre img { width: 100%; height: 100%; object-fit: cover; }
.photo-duo-g, .photo-duo-d { display: none; }
.photo-duo figcaption, .legende {
  margin-top: .75rem;
  font-size: var(--t-petit); line-height: 1.4;
  color: var(--texte-2);
}
.voile-photo { position: relative; isolation: isolate; }
.voile-photo::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background: var(--voile-photo); }

/* =================================================================== 10. BILLET + SOUCHE : un document blanc (charte §10 : « Blanc (documents) »)
   Texte noir ; l'or y passe en or profond (5,9:1), jamais l'or Villa (2,5:1). */
.billet {
  --souche: 38%;       /* largeur de la souche (à gauche de la perforation) */
  --encoche: 12px;
  position: relative;
  display: grid; grid-template-columns: var(--souche) 1fr;
  color: var(--noir);
}
.billet-souche, .billet-talon {
  position: relative;
  background: var(--blanc);
  padding: clamp(1rem, .6rem + calc(1.6 * var(--vw)), 2rem);
}
.billet-souche {
  border-radius: var(--rayon) 0 0 var(--rayon);
  -webkit-mask: radial-gradient(circle at 100% 0, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) top / 100% 51% no-repeat,
                radial-gradient(circle at 100% 100%, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) bottom / 100% 51% no-repeat;
          mask: radial-gradient(circle at 100% 0, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) top / 100% 51% no-repeat,
                radial-gradient(circle at 100% 100%, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) bottom / 100% 51% no-repeat;
}
.billet-talon {
  border-radius: 0 var(--rayon) var(--rayon) 0;
  -webkit-mask: radial-gradient(circle at 0 0, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) top / 100% 51% no-repeat,
                radial-gradient(circle at 0 100%, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) bottom / 100% 51% no-repeat;
          mask: radial-gradient(circle at 0 0, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) top / 100% 51% no-repeat,
                radial-gradient(circle at 0 100%, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) bottom / 100% 51% no-repeat;
}
/* la perforation, en pointillé */
.billet-talon::before {
  content: ""; position: absolute; left: -1px; top: calc(var(--encoche) + 6px); bottom: calc(var(--encoche) + 6px); width: 2px;
  background: repeating-linear-gradient(to bottom, var(--encre) 0 6px, transparent 6px 12px);
}
.billet-jour { display: block; font-weight: 700; font-size: var(--t-petit); letter-spacing: .04em; }
.billet-date {
  display: block;
  font-family: var(--f-display); font-weight: 900; font-variation-settings: 'wdth' 50, 'wght' 900;
  font-size: clamp(2.75rem, 1.6rem + calc(5 * var(--vw)), 7rem); line-height: .84; letter-spacing: -.01em;
}
.billet-an { display: block; font-family: var(--f-display); font-weight: 900; font-variation-settings: 'wdth' 62, 'wght' 900; font-size: clamp(1.25rem, 1rem + calc(1.2 * var(--vw)), 2.25rem); line-height: 1; margin-top: .15em; }
.billet-titre { font-family: var(--f-display); font-weight: 900; font-variation-settings: 'wdth' 58, 'wght' 900; font-size: var(--t-titre); line-height: 1; }
.billet-lieu { margin-top: .4em; font-weight: 600; font-size: var(--t-petit); line-height: 1.35; }
/* 12.10.2026 (Yann) : sur le billet « Je participe », l'info principale est l'événement : son nom passe en grand, en or profond ;
   la question (« Alors, on y va ? ») reste au-dessus, plus petite, et « Je participe » n'est plus que le bouton. */
.billet-titre--grand { font-size: clamp(2.4rem, 1.5rem + calc(3.6 * var(--vw)), 5.25rem); line-height: .92; color: var(--or-profond); text-wrap: balance; }
.billet-talon .billet-titre.billet-titre--grand { margin-top: .35em; }
.billet-talon > .billet-titre--grand:first-child { margin-top: 0; }
.billet-info { margin-top: .3em; font-size: var(--t-petit); color: var(--encre-douce); }
.billet .bouton { width: 100%; margin-top: 1rem; }
/* téléphone : la souche passe au-dessus du talon, la perforation devient horizontale */
@media (max-width: 599px) {
  .billet--adaptatif { grid-template-columns: 1fr; }
  .billet--adaptatif .billet-souche {
    border-radius: var(--rayon) var(--rayon) 0 0;
    -webkit-mask: radial-gradient(circle at 0 100%, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) left / 51% 100% no-repeat,
                  radial-gradient(circle at 100% 100%, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) right / 51% 100% no-repeat;
            mask: radial-gradient(circle at 0 100%, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) left / 51% 100% no-repeat,
                  radial-gradient(circle at 100% 100%, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) right / 51% 100% no-repeat;
  }
  .billet--adaptatif .billet-talon {
    border-radius: 0 0 var(--rayon) var(--rayon);
    -webkit-mask: radial-gradient(circle at 0 0, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) left / 51% 100% no-repeat,
                  radial-gradient(circle at 100% 0, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) right / 51% 100% no-repeat;
            mask: radial-gradient(circle at 0 0, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) left / 51% 100% no-repeat,
                  radial-gradient(circle at 100% 0, transparent var(--encoche), #000 calc(var(--encoche) + .5px)) right / 51% 100% no-repeat;
  }
  .billet--adaptatif .billet-talon::before {
    left: calc(var(--encoche) + 6px); right: calc(var(--encoche) + 6px); top: -1px; bottom: auto; width: auto; height: 2px;
    background: repeating-linear-gradient(to right, var(--encre) 0 6px, transparent 6px 12px);
  }
  .billet--adaptatif .billet-souche { transform-origin: 0 100%; }
}
/* la souche se détache : prise franche (déclenchée par .billet--prise ou au défilement, voir pages) */
.billet-souche { transition: translate 520ms var(--prise), rotate 520ms var(--prise); transform-origin: 100% 0; }
.billet--prise .billet-souche { translate: -10px 8px; rotate: -3deg; }

/* =================================================================== 11. CARTE MEMBRE « Toi | + 1 invité·e » */
.membre {
  --part: 58%;
  display: grid; grid-template-rows: auto 1fr auto;
  background: var(--noir-2); color: var(--texte);
  border: 1px solid var(--ligne); border-radius: var(--rayon);
  overflow: clip;
}
.membre-tete {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  padding: 1.1rem 1.25rem .9rem;
}
.membre-nom { font-family: var(--f-display); font-weight: 900; font-variation-settings: var(--plein); font-size: var(--t-h3); line-height: .9; text-transform: uppercase; }
.membre-prix { font-family: var(--f-display); font-weight: 900; font-variation-settings: 'wdth' 70, 'wght' 900; font-size: var(--t-titre); line-height: 1; white-space: nowrap; }
.membre-prix span { font-family: var(--f-texte); font-size: var(--t-petit); font-weight: 500; font-variation-settings: normal; }
.membre-duo { display: grid; grid-template-columns: var(--part) 1fr; }
.membre-toi, .membre-invite { padding: 1rem 1.25rem 1.25rem; font-size: var(--t-petit); line-height: 1.4; }
.membre-toi { background: var(--suit); }
.membre-invite { background: var(--guide); border-left: var(--fil) solid var(--or); }
.membre-qui { margin-bottom: .5rem; font-family: var(--f-display); font-weight: 300; font-variation-settings: 'wdth' 125, 'wght' 300; font-size: var(--t-titre); line-height: 1; }
.membre-toi li + li { margin-top: .35rem; }
.membre-toi li { padding-left: 1em; text-indent: -1em; }
.membre-toi li::before { content: "·"; display: inline-block; width: 1em; text-indent: 0; font-weight: 900; }
.membre .bouton { margin: 0; width: 100%; }
@media (max-width: 21.9rem) { .membre-duo { grid-template-columns: 1fr; } .membre-invite { border-left: 0; border-top: var(--fil) solid var(--or); } }

/* =================================================================== 12. CHAMP QUESTION | RÉPONSE, avec le y de validation */
.champ {
  position: relative; isolation: isolate;
  display: grid; grid-template-columns: var(--part-suit) 1fr; align-items: end;
  background: var(--fond-couture);
  transition: gap 300ms var(--prise);
}
/* le grain d'impression (10 %) continue sous les champs et sous l'envoi : la matière ne s'arrête pas au formulaire */
.champ::before, .formulaire-envoi::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: var(--grain); background-size: var(--grain-taille) var(--grain-taille); opacity: var(--grain-opacite);
}
.champ + .champ { margin-top: 2px; }
.champ-q {
  align-self: stretch; display: flex; align-items: flex-end; justify-content: flex-end;
  padding: 1.1rem clamp(.8rem, calc(2 * var(--vw)), 1.75rem) .9rem var(--marge);
  font-family: var(--f-display); font-weight: 300; font-variation-settings: 'wdth' 125, 'wght' 300;
  font-size: clamp(1.5rem, 1.1rem + calc(1.7 * var(--vw)), 2.5rem); line-height: 1.02; text-align: right;
  transition: translate 300ms var(--prise);
}
.champ-r { position: relative; padding: 1.1rem var(--marge) .9rem clamp(.8rem, calc(2 * var(--vw)), 1.75rem); transition: translate 300ms var(--prise); }
.champ-saisie {
  width: 100%; min-height: 48px; padding: .35em 0 .3em;
  border: 0; border-bottom: 2px solid var(--or); border-radius: 0;
  background: transparent; color: var(--texte);
  font-family: var(--f-display); font-weight: 900; font-variation-settings: 'wdth' 70, 'wght' 900;
  font-size: clamp(1.25rem, 1rem + calc(1 * var(--vw)), 1.75rem);
  transition: border-color 200ms var(--elan), background-color 200ms var(--elan);
}
.champ-saisie:hover { background: var(--voile-papier); }
.champ-saisie:focus-visible { outline-offset: 2px; background: var(--voile-papier); }
textarea.champ-saisie { min-height: 7rem; resize: vertical; font-family: var(--f-texte); font-weight: 500; font-variation-settings: normal; font-size: var(--t-corps); line-height: 1.45; }
select.champ-saisie { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--or) 50%), linear-gradient(135deg, var(--or) 50%, transparent 50%); background-position: right .9em center, right .45em center; background-size: .45em .45em; background-repeat: no-repeat; padding-right: 1.6em; }
select.champ-saisie option { color: var(--texte); background: var(--noir-2); }
.champ-aide { display: block; margin-top: .45rem; font-size: var(--t-petit); }
/* le y de validation, sur le filet or */
.champ-y {
  position: absolute; left: var(--part-suit); bottom: 1.3rem;
  width: 2rem; height: 2rem; margin-left: -1rem;
  display: grid; place-items: center;
  border-radius: 50%; background: var(--or); color: var(--noir);
  font: 900 1.15rem/1 var(--f-display); font-variation-settings: var(--noeud);
  scale: 0; transition: scale 360ms var(--prise);
  pointer-events: none;
}
.champ:has(.champ-saisie:user-valid) .champ-y, .champ--ok .champ-y { scale: 1; }
/* il manque une moitié : les deux moitiés s'écartent de 8 px, le texte le dit */
.champ--manque .champ-q, .champ:has(.champ-saisie:user-invalid) .champ-q { translate: -4px 0; }
.champ--manque .champ-r, .champ:has(.champ-saisie:user-invalid) .champ-r { translate: 4px 0; }
.champ--manque, .champ:has(.champ-saisie:user-invalid) { background: var(--fond-touche); }
.champ-erreur {
  grid-column: 2; padding: 0 var(--marge) .9rem clamp(.8rem, calc(2 * var(--vw)), 1.75rem);
  font-size: var(--t-petit); font-weight: 700;
}
.champ-erreur:empty { display: none; }
.champ-erreur::before { content: "↑ "; }
/* une colonne : la question au-dessus de la réponse. 11.10.2026 : sur tout téléphone (< 600 px), et plus seulement au
   zoom 400–500 % : à 375 px, le champ ne faisait que 177 px de large à côté de sa question (une adresse e-mail n'y
   tenait pas). Le champ prend toute la largeur ; le y de validation passe en haut à droite. */
@media (max-width: 599px) {
  .champ { grid-template-columns: 1fr; }
  .champ-q { justify-content: flex-start; text-align: left; padding-left: var(--marge); }
  .champ-r, .champ-erreur { padding-left: var(--marge); grid-column: 1; }
  .champ-y { left: auto; right: var(--marge); bottom: auto; top: 1rem; }
}
/* annonce d'envoi par e-mail : dit AVANT l'envoi */
.formulaire-envoi { position: relative; isolation: isolate; display: grid; grid-template-columns: var(--part-suit) 1fr; align-items: center; padding-block: 1.5rem; background: var(--fond-couture); }
.formulaire-envoi > :first-child { justify-self: end; padding-right: clamp(.8rem, calc(2 * var(--vw)), 1.75rem); text-align: right; font-size: var(--t-petit); padding-left: var(--marge); }
.formulaire-envoi > :last-child { padding-left: clamp(.8rem, calc(2 * var(--vw)), 1.75rem); padding-right: var(--marge); }
/* une colonne comme les champs (sinon la phrase, alignée sur la couture, sort à gauche de l'écran) ; 11.10.2026 : sur tout
   téléphone (< 600 px), comme les champs (à 375 px, la phrase tenait en sept lignes de deux mots) */
@media (max-width: 599px) {
  .formulaire-envoi { grid-template-columns: 1fr; row-gap: .75rem; }
  .formulaire-envoi > :first-child { justify-self: start; text-align: left; padding-right: var(--marge); }
  .formulaire-envoi > :last-child { padding-left: var(--marge); }
}

/* =================================================================== 13. PAS D'AVANT | PAS D'APRÈS
   La bande blanche de la page (charte §07 : noir 60 %, blanc 20 %, or 15 %) : texte noir, l'or en or profond,
   le filet or au milieu. */
.pas-nav {
  display: grid; grid-template-columns: var(--part-suit) var(--part-guide);
  background: var(--blanc);
  color: var(--noir);
  position: relative; isolation: isolate;
}
.pas-nav .pas-sens { color: var(--or-profond); }
.pas-nav a:focus-visible { outline-color: var(--noir); }
.pas-nav a {
  display: grid; align-content: center; gap: .35rem;
  min-height: clamp(8rem, 6rem + calc(8 * var(--vw)), 14rem);
  padding: 1.5rem clamp(.9rem, calc(2.5 * var(--vw)), 3rem);
  color: inherit; text-decoration: none;
  transition: background-color 300ms var(--elan);
}
.pas-nav .pas-avant { justify-items: end; text-align: right; padding-left: var(--marge); }
.pas-nav .pas-apres { padding-right: var(--marge); }
.pas-sens { display: inline-flex; align-items: center; gap: .5em; font-size: var(--t-petit); font-weight: 700; }
.pas-sens .fleche { width: 1.4em; transition: translate 360ms var(--prise); }
.pas-titre {
  font-family: var(--f-display); font-weight: 900; font-variation-settings: var(--plein);
  font-size: clamp(1.75rem, 1rem + calc(3.2 * var(--vw)), 4.5rem); line-height: .92;
  text-wrap: balance;   /* 11.10.2026 : « Reprendre / la main » plutôt que « Reprendre la / main » */
  transition: translate 420ms var(--prise);
}
.pas-avant:hover .pas-titre, .pas-avant:focus-visible .pas-titre { translate: -.25em 0; }
.pas-apres:hover .pas-titre, .pas-apres:focus-visible .pas-titre { translate: .25em 0; }
.pas-avant:hover .fleche, .pas-avant:focus-visible .fleche { translate: -.3em 0; }
.pas-apres:hover .fleche, .pas-apres:focus-visible .fleche { translate: .3em 0; }
.pas-nav a:hover { background: color-mix(in srgb, var(--or) 14%, var(--blanc)); }
.pas-nav a:active { translate: 0 2px; }
.pas-nav a:focus-visible { outline-offset: -6px; }
@media (max-width: 21.9rem) {
  .pas-nav { grid-template-columns: 1fr; } .pas-nav .pas-avant { justify-items: start; text-align: left; }
  .pas-nav a { min-height: 0; }   /* 11.10.2026 : les deux pas empilés ne gardent pas chacun 8 rem de blanc */
}
/* 11.10.2026 : sur deux colonnes, « pas d’avant » et « pas d’après » sur la même ligne, et les deux titres partent à la
   même hauteur, même si l'un fait trois lignes et l'autre deux (avant : chaque moitié centrée pour elle-même, les deux
   étiquettes décalées). Une sous-grille : deux rangées partagées (étiquette, titre) entre deux rangées souples qui
   centrent le tout. Sans sous-grille : chaque moitié reste centrée, comme avant. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 21.95rem) {
    .pas-nav { grid-template-rows: 1fr auto auto 1fr; min-height: clamp(8rem, 6rem + calc(8 * var(--vw)), 14rem); }
    .pas-nav a { grid-row: 1 / -1; grid-template-rows: subgrid; align-content: normal; min-height: 0; }
    .pas-nav .pas-sens { grid-row: 2; }
    .pas-nav .pas-titre { grid-row: 3; align-self: start; }
  }
}

/* =================================================================== 14. PIED « MERCI POUR LA DANSE » */
.pied {
  position: relative; isolation: isolate;
  background: var(--noir); color: var(--texte);
  border-top: var(--fil) solid var(--or);
  padding: var(--pas) 0 0;
  overflow: clip;
}
/* la photo de tout le monde (photo réelle, en couleur), voilée de noir en dégradé sous le texte (charte §10, §11) */
.pied-photo { position: absolute; left: 0; right: 0; top: 0; height: min(78%, 46rem); z-index: -3; }
.pied-photo img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 35%; }
.pied::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: min(78%, 46rem); z-index: -2; pointer-events: none;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--noir) 74%, transparent) 0%, color-mix(in srgb, var(--noir) 84%, transparent) 55%, var(--noir) 100%);
}
.pied::before { /* le filet or continue jusque dans le pied */
  content: ""; position: absolute; top: 0; bottom: 0; left: var(--part-suit); width: var(--fil); margin-left: calc(var(--fil) / -2);
  background: var(--or); z-index: -1;
  display: none;   /* 06.10.2026 : plus de ligne verticale */
}
.pied-merci {
  display: grid; grid-template-columns: var(--part-suit) 1fr;
  font-family: var(--f-display); font-size: var(--t-h2); line-height: .9;
}
/* la question d'abord (à gauche), la réponse un temps plus bas (à droite) : l'ordre de lecture tient ligne à ligne */
.pied-merci .duo-q { grid-row: 1; justify-self: end; padding-right: .22em; text-align: right; }
.pied-merci .duo-r { grid-row: 2; grid-column: 2; padding-left: .2em; }
@media (max-width: 599px) { .pied-merci .duo-q { font-variation-settings: 'wdth' 100, 'wght' 200; } }
/* le disque du logo descend se poser sur le filet (scroll-driven, une fois ; frame finale = posé). Une translation
   seulement : la charte interdit de pivoter, déformer ou recolorer le logo. Repli : main.js observe .pied-logo. */
.pied-logo {
  position: relative; z-index: 1;
  width: clamp(7rem, 5rem + calc(9 * var(--vw)), 13rem);
  margin: clamp(2rem, calc(5 * var(--vw)), 4rem) 0 clamp(2rem, calc(5 * var(--vw)), 4rem) calc(var(--part-suit) - clamp(7rem, 5rem + calc(9 * var(--vw)), 13rem) / 2);
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .pied-logo {
      animation-name: pied-pose; animation-duration: 1ms; animation-timing-function: var(--prise); animation-fill-mode: both;
      animation-timeline: view(); animation-range: entry 0% cover 50%;
    }
  }
}
@keyframes pied-pose { from { translate: 0 -30%; } }
.sans-sd .pied-logo { transition: translate 900ms var(--prise); }
.sans-sd .pied-logo:not(.vu) { translate: 0 -30%; }
.pied-duo { display: grid; grid-template-columns: var(--part-suit) 1fr; row-gap: .4rem; }
.pied-duo > :nth-child(odd) { justify-self: safe end; padding-right: clamp(.8rem, calc(2.4 * var(--vw)), 2.5rem); text-align: right; }   /* safe : si un mot dépasse la colonne, il ne sort pas de l'écran à gauche */
.pied-duo > .pied-slogan:nth-child(odd) { padding-left: var(--marge); }   /* 10.10.2026 (audit P1-9) : le slogan garde la marge du cadre (à 1440, « « Partageons notre passion, » commençait à 7 px du bord) */
.pied-duo > :nth-child(even) { padding-left: clamp(.8rem, calc(2.4 * var(--vw)), 2.5rem); }
.pied-slogan { font-family: var(--f-display); font-size: clamp(1.25rem, .95rem + calc(1.4 * var(--vw)), 2.25rem); line-height: 1.05; }
.pied-slogan .q { font-weight: 300; font-variation-settings: 'wdth' 125, 'wght' 300; }
.pied-slogan .r { font-weight: 900; font-variation-settings: var(--plein); }
.pied-slogan--en { margin-top: .35rem; font-size: clamp(1.05rem, .9rem + calc(.8 * var(--vw)), 1.6rem); }
/* téléphone : « Partageons / notre passion, tient dans la colonne de 45 % avec sa marge (à 375 px, le guillemet sortait
   de 7 px à gauche ; wdth 100 : la ligne la plus longue commence à 22 px du bord) */
@media (max-width: 599px) { .pied-slogan .q { font-variation-settings: 'wdth' 100, 'wght' 300; } }
/* règle des accents (11.10.2026, audit §17) : pas de délié d'Anybody de graisse ≤ 300 sous 20 px (ses accents, minuscules,
   disparaissent à densité 1) : Epilogue à la place. La ligne anglaise du slogan passe sous 20 px en dessous de 700 px. */
@media (max-width: 699px) {
  .pied-slogan--en .q { font-family: var(--f-texte); font-weight: 300; font-variation-settings: normal; letter-spacing: -.005em; }
}
.pied-contact { margin-top: clamp(2.5rem, calc(6 * var(--vw)), 5rem); font-size: var(--t-petit); }
.pied-contact a { display: inline-flex; align-items: center; min-height: 44px; font-weight: 700; text-decoration: underline 1px; text-underline-offset: .3em; transition: text-underline-offset 240ms var(--prise); }
.pied-contact a:hover, .pied-contact a:focus-visible { text-underline-offset: .5em; text-decoration-thickness: 2px; }
.pied-contact a:active { translate: 0 1px; }
.pied-contact .sur-titre { margin-bottom: .35rem; opacity: 1; }
.pied-bas {   /* la signature or de la page : or plein, texte noir (charte §07, §13) */
  position: relative; z-index: 1;
  display: grid; grid-template-columns: var(--part-suit) 1fr;
  margin-top: clamp(2.5rem, calc(6 * var(--vw)), 5rem); padding-block: 1.1rem 1.4rem;
  background: var(--or); color: var(--noir);
  font-size: var(--t-mini); font-weight: 600; letter-spacing: .03em; line-height: 1.5;
}
.pied-bas a { text-decoration-color: var(--noir); }
.pied-bas a:hover { text-decoration-color: var(--noir); }
.pied-bas a:focus-visible { outline-color: var(--noir); }
.pied-bas > :first-child { justify-self: end; padding-right: clamp(.8rem, calc(2.4 * var(--vw)), 2.5rem); text-align: right; padding-left: var(--marge); }
.pied-bas > :last-child { padding-left: clamp(.8rem, calc(2.4 * var(--vw)), 2.5rem); padding-right: var(--marge); }
.pied-bas a { display: inline-block; min-height: 24px; padding-block: 2px; }
/* zones tactiles (11.10.2026, audit §20) : « Mentions légales » et « Contact » font 44 px de haut et s'écartent de 12 px
   (point médian compris). La ligne devient une rangée souple : quand elle passe à la ligne (351–374 px), les deux zones
   ne se chevauchent jamais. La première rangée remonte d'une demi-zone : son texte reste aligné sur la colonne de gauche. */
@media not all and (min-width: 900px), (pointer: coarse) {
  .pied-bas > p:last-child { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .4em; margin-top: min(0px, calc((1lh - 44px) / 2)); }
  .pied-bas a { display: inline-flex; align-items: center; min-height: 44px; padding-block: 0; }
}
/* 11.10.2026 : dans la colonne de 55 % (téléphone, 2 colonnes), « Maquette 2026 » passait à la ligne avec son point
   (« · Maquette 2026 » en début de ligne) : il prend sa propre ligne, sans le point. En une colonne (≤ 21,9 rem), tout
   tient sur une ligne. */
@media (min-width: 21.95rem) and (max-width: 899px) {
  .pied-maquette { flex-basis: 100%; }
  .pied-point { display: none; }
}
@media (max-width: 21.9rem) {
  .pied-merci, .pied-duo, .pied-bas { grid-template-columns: 1fr; }
  .pied-merci .duo-q, .pied-duo > :nth-child(odd), .pied-bas > :first-child { justify-self: start; text-align: left; padding-left: var(--marge); }
  .pied-duo > :nth-child(even), .pied-merci .duo-r { padding-left: var(--marge); }
  /* 11.10.2026 (P2) : en une colonne, le pied faisait 1,4 écran à 320 × 640 (902 px). Resserré en CSS seulement : marges,
     et l'e-mail et le téléphone, Instagram et Facebook, deux par ligne (la ligne la plus longue tient à 320 px). */
  .pied { padding-top: 3rem; }
  .pied-logo { margin-block: 1.5rem; }
  .pied-contact, .pied-bas { margin-top: 2rem; }
  .pied-contact address > br:first-of-type, .pied-contact > div > br { display: none; }
  .pied-contact address > a:first-of-type, .pied-contact > div > a:first-of-type { margin-right: 1.25rem; }
  .pied-contact > div { margin-top: .9rem; }   /* « Suivre » ne colle plus à l'adresse (11.10.2026) */
}

/* =================================================================== 15. BLOC VIVANT « Le mot du comité » (daté, signé, livré VIDE) */
.bloc-vivant {
  display: grid; grid-template-columns: var(--part-suit) 1fr;
  background: var(--fond-couture);
}
.bloc-vivant > header { justify-self: end; padding: var(--pas) clamp(.8rem, calc(2.4 * var(--vw)), 2.5rem) var(--pas) var(--marge); text-align: right; }
.bloc-vivant-titre { font-family: var(--f-display); font-size: clamp(2.25rem, 1.4rem + calc(3.6 * var(--vw)), 5.5rem); line-height: .9; }
.bloc-vivant-titre .duo-q, .bloc-vivant-titre .duo-r { display: block; }
/* délié 100 seulement à 48 px et plus (≥ 45 rem de large) ; en dessous, un délié 300 */
.bloc-vivant-titre .duo-q { font-weight: 300; font-variation-settings: 'wdth' 125, 'wght' 300; }
@media (min-width: 45rem) { .bloc-vivant-titre .duo-q { font-weight: 200; font-variation-settings: 'wdth' 125, 'wght' 200; } }
.bloc-vivant-date { margin-top: 1rem; font-size: var(--t-petit); font-weight: 700; }
.bloc-vivant-corps { padding: var(--pas) var(--marge) var(--pas) clamp(.8rem, calc(2.4 * var(--vw)), 2.5rem); max-width: calc(var(--mesure-texte) + 6rem); }
.bloc-vivant-vide {
  display: grid; place-items: center; min-height: 10rem; padding: 1.5rem;
  border: 2px dashed var(--or); border-radius: var(--rayon);
  font-weight: 700; text-align: center;
}
.bloc-vivant-signature { margin-top: 1rem; font-weight: 700; }

/* =================================================================== 16. TEXTES : citation verbatim, fait, liste à pas */
.citation {
  font-family: var(--f-display); font-weight: 300; font-variation-settings: 'wdth' 110, 'wght' 300;
  font-size: clamp(1.5rem, 1.05rem + calc(1.9 * var(--vw)), 2.75rem); line-height: 1.12;
  quotes: "« " " »";
}
.citation p::before { content: open-quote; }
.citation p::after { content: close-quote; }
.citation-source { display: block; margin-top: .9rem; font-family: var(--f-texte); font-size: var(--t-petit); font-weight: 600; font-variation-settings: normal; }
.fait { font-family: var(--f-display); font-weight: 900; font-variation-settings: var(--plein); font-size: var(--t-h3); line-height: .9; color: var(--or); }   /* dates et chiffres en plein : or */
.texte { max-width: var(--mesure-texte); }
/* mot qui ne se coupe pas (« e-mail », « 21 h 45 ») ; dans un libellé de champ, envelopper TOUT le libellé dans un seul
   <span> (.champ-q est un flex : un nœud texte suivi d'un span y perd son espace) */
.insecable { white-space: nowrap; }
.texte > * + * { margin-top: 1em; }
.petit { font-size: var(--t-petit); }

/* =================================================================== 17. CHAPITRE (section de page) */
.chapitre { position: relative; overflow-x: clip; }
.chapitre-tete { padding: var(--pas) var(--marge) 0; }

/* =================================================================== 17 bis. LA NUIT : un noir plat
   (l'ancienne lumière de piste WebGL mélangeait deux couleurs : retirée. Aucune animation continue.) */
.nuit-fond { display: none; }

/* =================================================================== 17 ter. AGENDA : la note de la série, le cartouche date, le statut
   Pré-rendus par tools/agenda.cjs (assets/data/evenements.json) sur l'accueil, /agenda/ et les pages d'événement.
   La note : une seule par écran, avec la maison ; le texte posé dessus est celui de la charte (§08). Un événement passé
   perd sa note (noir-3). Le statut est une pastille noire (lisible sur noir, sur photo et sur un billet blanc). */
.note-rouge  { --note: var(--rouge);  --sur-note: var(--blanc); }   /* Sunday Vibes : blanc sur rouge (5,0:1) */
.note-or     { --note: var(--or);     --sur-note: var(--noir); }    /* Winter : la maison */
.note-orange { --note: var(--orange); --sur-note: var(--noir); }    /* Spring */
.note-ciel   { --note: var(--ciel);   --sur-note: var(--noir); }    /* Summer */
.note-passe  { --note: var(--noir-3); --sur-note: var(--texte-2); }
.cartouche {
  position: relative;   /* la date en toutes lettres (.sr) reste posée sur la note, pas sur le papier autour */
  display: inline-grid; justify-items: center; align-content: center; flex: none;
  min-width: 4.6em; margin: 0; padding: .5em .7em .55em;
  background: var(--note, var(--or)); color: var(--sur-note, var(--noir));
  font-family: var(--f-display); line-height: .9; text-align: center; text-transform: uppercase;
}
.cartouche-j, .cartouche-m { font-size: .75em; font-weight: 800; font-variation-settings: 'wdth' 70, 'wght' 800; letter-spacing: .06em; white-space: nowrap; }
.cartouche-d { font-size: 2.6em; font-weight: 900; font-variation-settings: 'wdth' 56, 'wght' 900; line-height: .92; }
.cartouche--petit { font-size: .75rem; min-width: 4em; }
.statut {
  display: inline-flex; align-items: center; gap: .45em;
  padding: .5em .85em .45em; border: 1px solid currentColor; border-radius: 999px;
  background: var(--noir); color: var(--statut, var(--texte-2));
  font: 700 var(--t-mini)/1 var(--f-texte); letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
}
.statut::before { content: ""; width: .6em; height: .6em; border-radius: 50%; background: currentColor; }
.statut--billetterie { --statut: var(--or); }
.statut--dernieres { --statut: var(--or-clair); }
.statut--complet { --statut: var(--texte); }
.statut--bientot { --statut: var(--texte-2); }
.statut--termine { --statut: var(--texte-3); }
.statut--gratuit { --statut: var(--or); }   /* un récurrent sans billetterie (Bachata Movida Nights) */

/* =================================================================== 17 quater. PARTAGER (08.10.2026)
   Pages d'événement : un bouton contour or (.bouton--fil) ; cartes de /agenda/ : un petit lien. Masqué sans JavaScript
   ([hidden], main.js le montre). Feuille native (navigator.share) si elle existe ; sinon le menu (popover natif), posé
   sous le bouton (ancrage CSS ; repli : centré). Aucun logo de marque : des mots. */
.partager { display: inline-flex; }
/* 11.10.2026 : avec JavaScript, « Partager » a sa place dès le premier rendu (main.js le montre ensuite, sans rien
   déplacer). Son arrivée après le premier rendu décalait le héros des pages d'événement et les cartes de /agenda/
   (CLS au chargement, jusqu'à 0,12 à 1440 quand le module arrivait tard). Sans JavaScript : masqué, comme avant. */
@media (scripting: enabled) { .partager[hidden] { display: inline-flex !important; } }
.partager-icone { width: 1.15em; height: 1.15em; flex: none; overflow: visible; }
.partager-lien {
  display: inline-flex; align-items: center; gap: .4em; min-height: 44px; padding: 0 .15em;
  border: 0; background: none; color: inherit; cursor: pointer;
  font: 700 var(--t-petit)/1.2 var(--f-texte); text-decoration: underline 2px var(--or); text-underline-offset: .3em;
}
.partager-lien:hover { text-decoration-color: currentColor; }
.partager-menu {
  width: min(19rem, calc(calc(100 * var(--vw)) - 2 * var(--marge)));
  margin: auto; padding: .9rem; border: 2px solid var(--or); border-radius: var(--rayon);
  background: var(--noir-2); color: var(--texte);
  box-shadow: 0 1rem 2.5rem var(--ombre-forte);
}
.partager-menu:popover-open { display: grid; gap: .4rem; }
.partager-menu::backdrop { background: transparent; }
@supports (position-anchor: --a) {
  /* le menu suit son bouton ; il disparaît quand le bouton sort de l'écran (jamais sur la barre) */
  .partager-menu { inset: auto; margin: .5rem 0; position-area: block-end span-inline-end; position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline; position-visibility: anchors-visible; }
}
.partager-titre { margin-bottom: .2rem; font: 700 var(--t-mini)/1.2 var(--f-texte); letter-spacing: .16em; text-transform: uppercase; color: var(--or); }
.partager-choix {
  display: flex; align-items: center; justify-content: space-between; gap: .6em;
  min-height: 46px; padding: .5rem 1rem; border: 1px solid var(--ligne-forte); border-radius: 999px;
  background: transparent; color: var(--texte); cursor: pointer; text-align: left; text-decoration: none;
  font: 700 var(--t-petit)/1.2 var(--f-texte);
  transition: border-color 200ms var(--elan), color 200ms var(--elan);
}
.partager-choix:hover { border-color: var(--or); color: var(--or-clair); text-decoration: none; }
button.partager-choix { display: block; }   /* « Copier le lien (pour Instagram) » : le texte passe à la ligne d'un bloc */
.partager-pour { font-weight: 500; color: var(--texte-2); }
.partager-dit { min-height: 1.3em; font: 700 var(--t-mini)/1.3 var(--f-texte); color: var(--or); overflow-wrap: anywhere; }

/* =================================================================== 18. TRÈS PETIT ÉCRAN / ZOOM 400–500 % (≤ 21,9 rem)
   Rien ne doit être coupé : le délié se serre (wdth), la réponse reste compressée, le bandeau passe à la ligne. */
@media (max-width: 21.9rem) {
  .bandeau { flex-wrap: wrap; }
  .bandeau p { white-space: normal; }
  .duo-q, .duo-titre .axe-q { font-variation-settings: 'wdth' 72, 'wght' 200; }
  .duo-titre .axe-r { font-variation-settings: var(--plein); }
  .duo-titre, .pas-titre, .couple-coupe { overflow-wrap: anywhere; }
  .journee-pas .pas-g, .journee-pas .pas-d { font-size: 1.5rem; }
  .barre-journee { position: static; translate: none; padding: 0 .45em; font-size: .8125rem; }
  .barre { gap: .35rem; }
  .cta-participe { padding: .3rem .6rem; font-size: .8125rem; }
}
