/* ═══════════════════════════════════════════════════════════
   Les Massiliades — site stylesheet
   Tokens (fonts/colors/typography/spacing) + base + components.
   ═══════════════════════════════════════════════════════════ */

/* Les fichiers de tokens portent leur propre ?v= : sans lui, bumper
   styles.css ne suffit pas — le navigateur reprend les tokens en cache
   et une valeur modifiee ici semble sans effet. Les incrementer EN MEME
   TEMPS que styles.css. */
@import "fonts.css?v=14";
@import "colors.css?v=14";
@import "typography.css?v=14";
@import "spacing.css?v=14";

/* ── Base ─────────────────────────────────────────────────── */
html, body { margin: 0; padding: 0; }
body {
  background: var(--stage);
  color: var(--text);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  /* clip et NON hidden. `hidden` fait de body un conteneur de defilement,
     ce qui annule le position:sticky de la barre de navigation : elle
     partait vers le haut au lieu de rester. `clip` decoupe le debordement
     horizontal sans creer ce conteneur, donc la barre tient. */
  overflow-x: clip;
}
* { box-sizing: border-box; }
img { max-width: 100%; display: block; }
a { color: var(--rose-fushia); }
a:hover { color: var(--vert-pale); }

@keyframes mass-float {
  0%, 100% { transform: translateY(0) rotate(var(--r, 0deg)); }
  50%      { transform: translateY(-16px) rotate(var(--r, 0deg)); }
}
@keyframes mass-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
@keyframes mass-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ── Placeholder (stands in for the oversized about-section
   mascot until a real file lands at assets/img/mascot-fuchsia.png) */
.ph-mascot {
  position: relative;
  display: grid;
  place-items: center;
  border-radius: var(--r-pill);
  background: radial-gradient(circle at 35% 30%, var(--rose-fushia), var(--violet) 78%);
}
.ph-mascot img { border-radius: inherit; }
.ph-mascot img[src=""],
.ph-mascot img:not([src]) { display: none; }

/* ── Hero mascot + hand-drawn doodles (notes / #) ─────────── */
.hero-mascot { position: relative; width: min(380px, 62vw); margin-bottom: 4px; }
.hero-mascot__img {
  width: 100%;
  display: block;
  filter: drop-shadow(0 18px 40px rgba(0, 0, 0, 0.5));
  animation: mass-float 7s ease-in-out infinite;
}
/* doodles are black-on-transparent hand-drawn PNGs, used as-is */
.hero-deco {
  position: absolute;
  height: auto;
  display: block;
  pointer-events: none;
}

/* ── NavBar ───────────────────────────────────────────────── */
.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
  padding: 16px var(--gutter);
  width: 100%;
  background: rgba(16, 16, 17, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
  font-family: var(--font-body);
  flex-wrap: wrap;
}
.navbar__brand { display: flex; align-items: center; gap: 12px; text-decoration: none; }
.navbar__brand img { height: 38px; width: auto; }
.navbar__brand .navbar__mascot { height: 46px; }
.navbar__brand span { font-family: var(--font-display); font-size: 1.6rem; color: var(--beige); }
.navbar__right { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }

/* burger (mobile only) */
.navbar__burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 46px;
  height: 46px;
  padding: 10px;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--r-sm);
  background: transparent;
  cursor: pointer;
}
.navbar__burger span {
  display: block;
  width: 100%;
  height: 3px;
  border-radius: 2px;
  background: var(--beige);
  transition: transform var(--dur-med) var(--ease-out), opacity var(--dur-fast);
}
/* burger → croix quand le menu est ouvert */
.navbar.is-open .navbar__burger span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.navbar.is-open .navbar__burger span:nth-child(2) { opacity: 0; }
.navbar.is-open .navbar__burger span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }
.navbar__links { display: flex; align-items: center; gap: var(--sp-2); list-style: none; margin: 0; padding: 0; flex-wrap: wrap; }
.navbar__links a {
  display: inline-block;
  padding: 8px 16px;
  border-radius: var(--r-pill);
  font-size: 0.9375rem;
  font-weight: var(--fw-bold);
  text-decoration: none;
  color: var(--beige);
  background: transparent;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.navbar__links a:hover { background: var(--beige-08); color: var(--beige); }
.navbar__links li.is-active a { color: var(--rose-fushia); background: var(--rose-12); }
.navbar__links li.is-active a:hover { background: var(--rose-12); }
.navbar__cta {
  margin-left: 8px;
  padding: 10px 22px;
  border-radius: var(--r-pill);
  background: var(--rose-fushia);
  color: var(--beige);
  font-weight: var(--fw-bold);
  font-size: 0.9375rem;
  text-decoration: none;
  transition: transform var(--dur-fast) var(--ease-bounce), filter var(--dur-fast);
}
.navbar__cta:hover { color: var(--beige); transform: translateY(-2px); filter: brightness(1.06); }

/* ── Bascule francais / anglais ─────────────────────────────
   Petit interrupteur a deux positions, la langue active en plein.
   `order: 1` l'envoie en fin de barre sur grand ecran ; sur mobile
   il repasse a 0 pour rester visible a cote du burger, menu ferme. */
.navbar__lang {
  order: 1;
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: var(--r-pill);

  /* Habillage « verre ». Trois couches qui font le volume :
     un fond a peine teinte, un lisere clair en haut qui imite le
     bord biseaute, et une ombre portee courte qui decolle la
     pastille de la barre. Le flou du fond fait le reste. */
  background: color-mix(in srgb, var(--beige) 7%, transparent);
  border: 1.5px solid color-mix(in srgb, var(--beige) 20%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--beige) 28%, transparent),
              inset 0 -1px 0 color-mix(in srgb, var(--noir) 22%, transparent),
              0 2px 10px rgba(0, 0, 0, 0.32);
  -webkit-backdrop-filter: blur(7px) saturate(1.35);
  backdrop-filter: blur(7px) saturate(1.35);
}
/* La distorsion du filtre SVG (voir <svg class="glass-defs"> dans les
   pages) ne s'applique qu'au FOND, jamais aux libelles : c'est un
   backdrop-filter. FR et EN restent donc parfaitement nets.
   Chromium sait lire un url() ici ; Safari et Firefox l'ignorent et
   gardent le flou ci-dessus, qui suffit a l'effet. */
@supports (backdrop-filter: url("#radio-glass")) {
  .navbar__lang {
    -webkit-backdrop-filter: blur(4px) saturate(1.4) url("#radio-glass");
    backdrop-filter: blur(4px) saturate(1.4) url("#radio-glass");
  }
}
/* Reflet. Le filtre de deplacement ne se voit que sur un fond qui a du
   grain ; la barre de nav est un aplat presque noir, il n'y avait donc
   rien a deformer. Ce degrade oblique apporte la brillance qui fait
   lire le verre quel que soit ce qu'il y a derriere. Tres peu appuye
   pour ne pas voiler les libelles. */
.navbar__lang::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(
    145deg,
    color-mix(in srgb, var(--beige) 16%, transparent) 0%,
    transparent 42%,
    transparent 74%,
    color-mix(in srgb, var(--beige) 7%, transparent) 100%
  );
}
/* Le <svg> porteur du filtre ne doit rien occuper dans la page. */
.glass-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.navbar__lang button {
  appearance: none;
  border: 0;
  cursor: pointer;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  line-height: 1;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.navbar__lang button:hover { color: var(--beige); background: var(--beige-08); }
.navbar__lang button.is-on { background: var(--beige); color: var(--gris-fonce); }
.navbar__lang button:focus-visible { outline: 2px solid var(--acc, var(--rose-fushia)); outline-offset: 2px; }

/* mobile : logo texte masqué (mascotte seule), onglets repliés dans le burger */
@media (max-width: 900px) {
  .navbar { flex-wrap: wrap; }
  .navbar__brand .navbar__logo { display: none; }
  .navbar__burger { display: flex; }
  .navbar__right {
    display: none;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: var(--sp-2);
    padding-top: var(--sp-4);
  }
  /* La bascule de langue reste visible menu ferme, entre la mascotte et
     le burger ; le panneau replie passe apres eux et va a la ligne. */
  .navbar__lang { order: 0; }
  .navbar__right { order: 1; }
  .navbar.is-open .navbar__right { display: flex; }
  .navbar__links { flex-direction: column; align-items: stretch; width: 100%; }
  .navbar__links a { display: block; text-align: center; padding: 13px 16px; font-size: 1.05rem; }
  .navbar__cta { margin-left: 0; text-align: center; padding: 14px 22px; font-size: 1.05rem; }
}

/* ── Button ───────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55em;
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  line-height: 1;
  letter-spacing: 0.01em;
  border-radius: var(--r-pill);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  padding: 13px 26px;
  font-size: 1rem;
  border: 2px solid transparent;
  transition: transform var(--dur-fast) var(--ease-bounce), filter var(--dur-fast) var(--ease-out),
              background var(--dur-med) var(--ease-out), color var(--dur-med) var(--ease-out),
              border-color var(--dur-med) var(--ease-out);
}
.btn:hover { transform: translateY(-2px); filter: brightness(1.06); }
.btn:active { transform: translateY(0) scale(0.97); }
.btn--lg { padding: 18px 40px; font-size: 1.1875rem; }
.btn--sm { padding: 9px 18px; font-size: 0.875rem; }
.btn--primary { background: var(--rose-fushia); color: var(--beige); border-color: var(--rose-fushia); }
.btn--primary:hover { color: var(--beige); }
.btn--light { background: var(--beige); color: var(--gris-fonce); border-color: var(--beige); }
.btn--light:hover { color: var(--gris-fonce); }
.btn--violet { background: var(--violet); color: var(--beige); border-color: var(--violet); }
.btn--violet:hover { color: var(--beige); }
.btn--vert { background: var(--vert-pale); color: var(--gris-fonce); border-color: var(--vert-pale); }
.btn--vert:hover { color: var(--gris-fonce); }
.btn--outline { background: transparent; color: var(--beige); border-color: var(--beige-16); }
.btn--outline:hover { color: var(--beige); }
/* Contour sobre au repos, qui se remplit de vert au survol —
   le vert de la page Tremplin, annoncé au moment du geste. */
.btn--outline-vert { background: transparent; color: var(--beige); border-color: var(--beige-16); }
.btn--outline-vert:hover,
.btn--outline-vert:focus-visible {
  background: var(--vert-pale);
  color: var(--gris-fonce);
  border-color: var(--vert-pale);
}
/* Meme principe en violet, pour les liens qui menent a la programmation. */
.btn--outline-violet { background: transparent; color: var(--beige); border-color: var(--beige-16); }
.btn--outline-violet:hover,
.btn--outline-violet:focus-visible {
  background: var(--violet);
  color: var(--beige);
  border-color: var(--violet);
}
/* Bouton reduit au texte : ni fond, ni contour, ni pastille. Il prend
   l'accent de sa page. Le rembourrage vertical ne se voit pas mais
   agrandit la zone tactile — une ligne de texte seule n'offre qu'une
   vingtaine de pixels a viser au doigt. */
.btn--texte {
  padding: 6px 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  /* Beige par defaut : la couleur neutre du site. Les variantes
     ci-dessous colorent les liens qui doivent l'etre. */
  color: var(--beige);
  font-size: var(--fs-sm);
  white-space: normal;
}
.btn--texte:hover,
.btn--texte:focus-visible {
  background: transparent;
  color: var(--beige);
  transform: none;
  filter: none;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.btn--texte:active { transform: none; }
/* Couleurs des liens texte : chacun prend celle de la page vers
   laquelle il mene. Le violet est eclairci de 30% vers le beige — pur,
   il ne donne que 3.03:1 sur le fond sombre, sous le seuil lisible. */
.btn--texte.btn--primary,
.btn--texte.btn--primary:hover { color: var(--rose-fushia); background: transparent; }
.btn--texte.btn--vert,
.btn--texte.btn--vert:hover { color: var(--vert-pale); background: transparent; }
.btn--texte.btn--violet,
.btn--texte.btn--violet:hover {
  color: color-mix(in srgb, var(--violet) 70%, var(--beige));
  background: transparent;
}

.btn--ghost { background: transparent; color: var(--beige); border-color: transparent; }
.btn--ghost:hover { color: var(--beige); }

/* ── SectionTitle ─────────────────────────────────────────── */
.section-title { display: flex; flex-direction: column; gap: 0.5em; }
.section-title--center { text-align: center; align-items: center; }
.section-title__eyebrow {
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--rose-fushia);
}
.section-title__eyebrow--lime { color: var(--vert-pale); }
/* Variante Botch : ni majuscules forcees ni interlettrage, la police
   porte deja le caractere. A n'employer que sur un texte sans apostrophe
   ni deux-points, que Botch rend sous forme d'etoile. */
.section-title__eyebrow--display {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.05rem, 2.2vw, 1.4rem);
  letter-spacing: var(--ls-display);
  text-transform: none;
  line-height: 1.1;
}
.section-title h2 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  color: var(--text);
  text-wrap: balance;
}
.section-title--display h2 { font-size: var(--fs-display); }
.section-title--title h2 { font-size: var(--fs-title); }

/* Grand titre : le surtitre a besoin de respirer davantage sous un
   corps aussi imposant. On garde en revanche le sous-titre collé au
   titre, pour qu'on lise bien les deux comme un seul ensemble. */
.section-title--display { gap: var(--sp-2); }
.section-title--display .section-title__eyebrow { margin-bottom: var(--sp-2); }
.section-title__sub {
  /* 8px sous un titre Botch de 44px : le sous-titre semblait coller au
     titre au lieu de le commenter. Mesure sur telephone a 390px. */
  margin: 6px 0 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-muted);
  max-width: 42ch;
}

/* ── ArtistCard / SurpriseCard ────────────────────────────── */
.artist-card {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  border: none;
  padding: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface);
  text-decoration: none;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-med) var(--ease-out), box-shadow var(--dur-med) var(--ease-out);
}
.artist-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-md), var(--shadow-glow); }
.artist-card img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-slow) var(--ease-out); }
.artist-card:hover img { transform: scale(1.05); }
.artist-card__scrim { position: absolute; inset: 0; background: linear-gradient(to top, rgba(16,16,17,0.92) 0%, rgba(16,16,17,0.35) 42%, rgba(16,16,17,0) 68%); }
.artist-card__tag {
  position: absolute; top: 14px; left: 14px;
  padding: 6px 12px; border-radius: var(--r-pill);
  background: var(--rose-fushia); color: var(--beige);
  font-weight: var(--fw-bold); font-size: var(--fs-xs);
  letter-spacing: 0.04em; text-transform: uppercase;
}
.artist-card__name {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 20px;
  font-family: var(--font-display); font-size: var(--fs-head); line-height: 1; color: var(--beige);
}

.surprise-card {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  border-radius: var(--r-lg);
  border: 2px dashed var(--rose-fushia);
  background: repeating-linear-gradient(135deg, var(--beige-08) 0 2px, transparent 2px 14px), var(--surface);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  overflow: hidden;
  transition: transform var(--dur-med) var(--ease-out), border-color var(--dur-med);
}
.surprise-card:hover { transform: translateY(-6px); }
.surprise-card--violet { border-color: var(--violet); }
.surprise-card--violet .surprise-card__q { color: var(--violet); }
.surprise-card--lime { border-color: var(--vert-pale); }
.surprise-card--lime .surprise-card__q { color: var(--vert-pale); }
.surprise-card__q { font-family: var(--font-display); font-size: clamp(4rem, 12vw, 7rem); line-height: 1; color: var(--rose-fushia); }
.surprise-card__label { font-weight: var(--fw-bold); font-size: var(--fs-xs); letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--text-muted); }

/* ── PartnerLogo ──────────────────────────────────────────── */
.partner-logo {
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9;
  padding: var(--sp-5);
  border-radius: var(--r-md);
  background: var(--beige);
  text-decoration: none;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-med) var(--ease-out), box-shadow var(--dur-med);
}
.partner-logo:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
/* tuile logo image (aperçu accueil) : logo contenu dans la tuile beige,
   halo dans la couleur du partenaire au survol */
.partner-logo--img img { max-width: 100%; max-height: 100%; object-fit: contain; }
.partner-logo--photo { padding: 0; position: relative; overflow: hidden; }
.partner-logo--photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.partner-logo--img:hover,
.partner-logo--photo:hover {
  box-shadow:
    var(--shadow-md),
    0 0 0 2px var(--acc, var(--rose-fushia)),
    0 6px 36px 2px color-mix(in srgb, var(--acc, var(--rose-fushia)) 40%, transparent);
}
.partner-logo--lead { aspect-ratio: 16 / 7; }
.partner-logo span {
  font-family: var(--font-display);
  font-size: 1.5rem;
  color: var(--gris-fonce);
  text-align: center;
  line-height: 1;
}
.partner-logo--lead span { font-size: var(--fs-head); }

/* ── Invitation a toucher la pochette (telephone) ───────────
   Posee par flip.js sur les cartes qui portent un data-audio.
   Reservee aux petits ecrans : sur ordinateur, le curseur et
   l'infobulle `title` font deja ce travail. */
.detail__cue { display: none; }

@media (max-width: 760px) {
  .detail__cue {
    position: absolute;
    left: 12px;
    bottom: 12px;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px 8px 11px;
    border-radius: var(--r-pill);
    background: color-mix(in srgb, var(--noir) 72%, transparent);
    border: 1.5px solid color-mix(in srgb, var(--acc, var(--rose-fushia)) 70%, transparent);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: var(--beige);
    font-family: var(--font-body);
    font-weight: var(--fw-bold);
    font-size: 0.75rem;
    line-height: 1;
    pointer-events: none;              /* le clic doit aller a la carte */
    animation: cue-pulse 2.4s ease-in-out infinite;
  }

  /* Triangle de lecture, dessine en bordures : pas d'image a charger. */
  .detail__cue-icon {
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 5px 0 5px 9px;
    border-color: transparent transparent transparent var(--acc, var(--rose-fushia));
  }

  /* Au repos on invite ; carte retournee, on annonce l'ecoute. */
  .detail__cue-label--actif { display: none; }
  .is-flipped .detail__cue-label--repos { display: none; }
  .is-flipped .detail__cue-label--actif { display: inline; }
  .is-flipped .detail__cue { animation: none; }
  /* Le triangle devient un carre de pause. */
  .is-flipped .detail__cue-icon {
    width: 8px;
    height: 9px;
    border: 0;
    background: var(--acc, var(--rose-fushia));
    border-radius: 1px;
  }

  @keyframes cue-pulse {
    0%, 100% { transform: scale(1); opacity: .92; }
    50%      { transform: scale(1.05); opacity: 1; }
  }
}
@media (prefers-reduced-motion: reduce) {
  .detail__cue { animation: none !important; }
}

/* ── Star ─────────────────────────────────────────────────── */
.star {
  display: inline-block;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}
.star--spin { animation: mass-spin 18s linear infinite; }

/* ── Footer ───────────────────────────────────────────────── */
.site-footer {
  border-top: 1px solid var(--border);
  padding: var(--sp-8) var(--gutter) var(--sp-6);
  font-family: var(--font-body);
  color: var(--text-muted);
}
.site-footer__top {
  max-width: var(--page-max);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-7);
  justify-content: space-between;
  align-items: flex-start;
}
.site-footer__brand { max-width: 340px; display: flex; flex-direction: column; gap: var(--sp-3); }
/* align-self indispensable : la colonne flex etire ses enfants sur toute
   la largeur par defaut, ce qui deformait le logo (46px de haut sur 340
   de large). Il garde ici ses proportions d'origine. */
.site-footer__brand img { height: 46px; width: auto; align-self: flex-start; }
.site-footer__brand p { margin: 0; font-size: var(--fs-sm); line-height: var(--lh-body); }
/* ── Logo de l'école, dans le pied de page ──────────────────
   Le fichier d'origine est en bleu marine : pose tel quel sur le fond
   noir de la page, il tombait à 1.44:1 — invisible. Il est detoure
   (77% de transparence) et aucun de ses pixels n'est blanc, donc son
   canal alpha peut servir de MASQUE : on le repeint entierement en
   beige, et les parties claires du logo restent des trous.
   Comme pour les doodles, l'url() se resout depuis CETTE feuille de
   style, d'ou le ../img/ et non assets/img/. */
.site-footer__ecm {
  display: inline-block;
  flex: none;
  width: 96px;
  aspect-ratio: 2072 / 764;
  background-color: var(--beige);
  -webkit-mask: url("../img/logo-centrale-mediterranee.png") left center / contain no-repeat;
  mask: url("../img/logo-centrale-mediterranee.png") left center / contain no-repeat;
  /* discret : present sans tirer l'oeil */
  opacity: .48;
  transition: opacity var(--dur-med) var(--ease-out);
}
.site-footer__ecm:hover { opacity: .72; }
/* Le logo et la ligne de copyright vont ensemble, alignes sur leur
   milieu. Ils se separent proprement si la place manque. */
.site-footer__copy {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}

.site-footer__cols { display: flex; gap: var(--sp-8); flex-wrap: wrap; }
.site-footer__col { display: flex; flex-direction: column; gap: var(--sp-3); }
.site-footer__col h3 {
  margin: 0; font-weight: var(--fw-bold); font-size: var(--fs-xs);
  letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--beige);
}
/* Une colonne peut porter plusieurs blocs (Suivez-nous puis Contactez-nous) :
   le second intertitre respire un peu plus que le gap de la colonne. */
.site-footer__col h3:not(:first-child) { margin-top: var(--sp-3); }
.site-footer__col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.site-footer__col a { color: var(--text-muted); text-decoration: none; font-size: var(--fs-sm); transition: color var(--dur-fast); }
.site-footer__col a:hover { color: var(--rose-fushia); }
.site-footer__bottom {
  max-width: var(--page-max);
  margin: var(--sp-7) auto 0;
  padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  justify-content: space-between;
  font-size: var(--fs-xs);
}
.site-footer__bottom span:last-child { color: var(--beige-dim); }

/* ── Programmation page ───────────────────────────────────── */
.prog-page { --acc: var(--violet); }

/* ── En-tetes de page a gros titre Botch ───────────────────
   Le titre est en Botch avec line-height .92 : les glyphes montent
   plus haut que leur boite. Sans marge propre, leur sommet venait
   se coller a la barre collante et paraissait rogne. D'ou ce
   decalage vers le bas, en plus du rembourrage du conteneur.
   Utilisee par la programmation et par les partenaires, qui ont le
   meme montage : gros titre a gauche, mascotte dans la marge droite. */
.page-header { padding-top: var(--sp-5); }

/* Au-dela de 760px la mascotte est visible, posee dans la marge
   droite. On reserve sa place : le titre se replie avant de passer
   dessous, au lieu de la recouvrir. La largeur reservee couvre la
   mascotte (144px) et son inclinaison. */
@media (min-width: 761px) {
  .page-header h1 { padding-right: 190px; }
}

.prog-eyebrow {
  font-weight: var(--fw-bold);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--acc);
}

/* on Programmation, the active tab wears the page accent (violet) */
.prog-page .navbar__links li.is-active a { color: var(--violet); background: var(--violet-16); }
.prog-page .navbar__links li.is-active a:hover { background: var(--violet-16); }

/* ── Partenaires page — theme: vert pale ──────────────────── */
/* La page partenaires est entierement rose : un seul accent, ni violet
   ni vert, pour que les trois maisons soient traitees a egalite. */
.part-page { --acc: var(--rose-fushia); }
.part-page .navbar__links li.is-active a { color: var(--rose-fushia); background: var(--rose-12); }
.part-page .navbar__links li.is-active a:hover { background: var(--rose-12); }

.ptile { transition: transform var(--dur-med) var(--ease-out), box-shadow var(--dur-med) var(--ease-out); }
.ptile:hover {
  transform: translateY(-6px);
  box-shadow:
    var(--shadow-md),
    0 0 0 1px color-mix(in srgb, var(--acc, var(--rose-fushia)) 65%, transparent),
    0 6px 44px 6px color-mix(in srgb, var(--acc, var(--rose-fushia)) 60%, transparent);
}

/* streaming round icon links */
.rnd {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1.5px solid var(--border-strong);
  background: var(--surface-raised);
  color: var(--beige);
  text-decoration: none;
  font-size: 1.05rem;
  transition: border-color var(--dur-fast), transform var(--dur-fast) var(--ease-bounce);
}
.rnd:hover { transform: translateY(-2px); border-color: var(--acc); color: var(--beige); }

/* video tile with play button */
.vtile {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-md);
  overflow: hidden;
  background: #000;
  text-decoration: none;
}
.vtile .play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 66px;
  height: 66px;
  border-radius: 50%;
  background: var(--acc);
  color: var(--beige);
  display: grid;
  place-items: center;
  font-size: 1.5rem;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
  transition: transform var(--dur-fast) var(--ease-bounce);
}
.vtile:hover .play { transform: scale(1.08); }

/* artist detail block */
.detail {
  border-top: 1px solid var(--border);
  padding: var(--sp-8) 0;
  display: grid;
  grid-template-columns: 0.82fr 1.18fr;
  gap: clamp(24px, 3.5vw, 52px);
  align-items: start;
}
@media (max-width: 760px) { .detail { grid-template-columns: 1fr; } }

/* a full-bleed, darkened photo behind a detail block, faded top + bottom */
.detail--bg {
  position: relative;
  isolation: isolate;
  border-top: none;
}
.detail--bg::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  /* full-bleed: stretch from the centred column to the viewport edges */
  left: calc(50% - 50vw);
  width: 100vw;
  z-index: -1;
  background:
    linear-gradient(rgba(16, 16, 17, 0.72), rgba(16, 16, 17, 0.72)),
    var(--detail-bg) center / cover no-repeat;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 20%, #000 80%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 20%, #000 80%, transparent 100%);
}

/* detail block that hosts an animated shader layer but no photo bg —
   just needs its own stacking context so the canvas (z-index:-1) sits
   behind the content. */
.detail--fx { position: relative; isolation: isolate; }

/* animated wave overlay — sits just above the concert photo,
   below the text and cards; fades in/out gently while the card is
   flipped (music playing). Kept very faint and blended to stay subtle. */
.detail__shader {
  position: absolute;
  bottom: 0;
  /* full-bleed, aligned with the section's viewport-wide photo */
  left: calc(50% - 50vw);
  width: 100vw;
  height: 67%;
  z-index: -1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.4s ease;
  mix-blend-mode: screen;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 34%, #000 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 34%, #000 100%);
}

/* artist detail artwork — bordered in the artist's accent colour,
   glows softly outward on hover */
.detail__art {
  border: 2px solid var(--acc, var(--rose-fushia));
  border-radius: var(--r-lg);
  transition: box-shadow var(--dur-med) var(--ease-out), transform 150ms ease-out;
  transform: perspective(800px) rotateX(0deg) rotateY(0deg);
  will-change: transform;
  perspective: 1200px;
}
.detail__art:hover {
  box-shadow: 0 0 0 1px var(--acc, var(--rose-fushia)), 0 0 22px 3px color-mix(in srgb, var(--acc, var(--rose-fushia)) 55%, transparent);
}

/* click-to-flip: cards with a revealed second photo rotate on their
   vertical axis to show it on the back */
.detail__art--flippable { cursor: pointer; }
.detail__art-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.7s cubic-bezier(0.65, 0, 0.35, 1);
}
.detail__art--flippable.is-flipped .detail__art-inner { transform: rotateY(180deg); }
.detail__art-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  border-radius: var(--r-lg);
  overflow: hidden;
}
.detail__art-face--back {
  transform: rotateY(180deg);
  background: var(--surface);
}
/* fill the whole face deterministically (absolute inset avoids the
   grid percentage-height quirk that left a grey band on Chrome) and
   anchor to the top so the image sits flush with the card's top edge */
.detail__art-face--back img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  padding: 0;
}

/* ── Page Partenaires ─────────────────────────────────────────
   Une rangée par partenaire : panneau logo clair d'un côté
   (les logos sont dessinés pour fond blanc), contenu de l'autre.
   L'accent (--acc) est posé sur l'article et colore la bordure,
   la pastille et le nom. --flip inverse le sens de la rangée. */
/* Rangee compacte : une petite vignette de logo posee a gauche, tout le
   texte a cote. Le logo ne fait plus un panneau, il fait une pastille —
   d'ou une rangee qui tient en quelques lignes au lieu d'occuper un
   ecran entier. Les logos restent sur fond beige : ils sont dessines
   pour du blanc et disparaitraient sur le fond noir de la page. */
.partner {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-5);
  align-items: start;
  padding: var(--sp-5) 0;
  border-top: 1px solid var(--border);
}
/* Le logo est pose nu : ni cadre, ni fond, ni ombre. Un fichier
   transparent a l'encre claire ressort donc seul sur le fond sombre.
   LECON DEJA PAYEE : un logo qui porte son propre fond blanc DANS le
   fichier garde ce rectangle blanc, et aucun CSS ne peut le retirer.
   C'est le seul critere a verifier avant de deposer un nouveau logo. */
/* La boite est un RECTANGLE fixe, pas un carre. Les cinq logos vont du
   carre (Crous, BDA) au tres allonge (hyperion, 4,27:1) : une boite
   carree de 76px aurait reduit les logotypes horizontaux a une bande de
   18px de haut, illisible. Largeur ET hauteur fixes gardent en plus les
   cinq colonnes de texte alignees d'une rangee a l'autre — un logo plus
   large que les autres decalerait sa rangee. object-fit: contain fait le
   reste : chaque logo occupe ce qu'il peut sans jamais se deformer. */
.partner__logo {
  position: relative;
  width: 108px;
  height: 72px;
  display: grid;
  place-items: center;
}
/* L'image est posee en ABSOLU sur toute la boite. Ce n'est pas de la
   coquetterie : mesure dans le navigateur, les deux logos CARRES (Crous,
   BDA) se rendaient en 108x108 dans une boite de 108x72 et mordaient sur
   la rangee voisine. Ni max-height: 100% ni height: 100% ne les
   contenaient — la hauteur en pourcentage ne se resolvait que pour les
   logos deja plus larges que hauts, et le rapport d'image reprenait la
   main pour les autres. En absolu avec inset: 0, la boite de l'image est
   exactement celle du conteneur positionne, sans pourcentage a resoudre ;
   object-fit: contain redimensionne le dessin a l'interieur. */
.partner__logo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* variante photo (portrait) : l'image remplit la vignette, coins adoucis */
.partner__logo--photo { overflow: hidden; border-radius: var(--r-md); }
.partner__logo--photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* gap de base : l'ecart minimal du bloc, entre le surtitre et le nom,
   qui vont ensemble. Les lignes suivantes reprennent de l'air une a une
   via leur propre margin-top — voir plus bas. Mesure sur telephone a
   390px : a 6px partout, le surtitre rose, le nom en Botch et la
   description se touchaient presque, et comme les deux premiers passent
   souvent sur DEUX lignes a cette largeur, le bloc formait un pave. */
.partner__body { display: flex; flex-direction: column; gap: 5px; }
/* Le metier passe en surtitre discret plutot qu'en pastille pleine :
   trois pastilles roses empilees pesaient plus que les noms. */
.partner__tag {
  align-self: flex-start;
  font-weight: 700;
  font-size: 0.6875rem;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--acc, var(--rose-fushia));
}
.partner__name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.375rem;
  line-height: 1;
  letter-spacing: var(--ls-display);
  color: var(--text);
}
/* Le nom du partenaire mene a son site. Il garde l'apparence du titre —
   pas de couleur de lien qui jurerait avec le Botch — et ne se souligne
   qu'au survol. */
.partner__name a { color: inherit; text-decoration: none; }
.partner__name a:hover,
.partner__name a:focus-visible {
  color: var(--acc, var(--rose-fushia));
  text-decoration: underline;
  text-underline-offset: 5px;
}
.partner__desc {
  margin: 5px 0 0;          /* respire apres le nom en Botch */
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--text-muted);
  max-width: 76ch;
}
/* Les prestations tiennent sur une ligne, separees par des points
   mediaux : trois pastilles a puces prenaient trois fois la place. */
.partner__offers {
  display: flex;
  flex-wrap: wrap;
  /* 4px d'interligne suffisaient tant que les prestations tenaient sur
     UNE ligne. Sous 560px elles passent a la ligne une par une et se
     retrouvaient collees : mesure a 4px d'ecart pour du texte de 13px. */
  gap: 7px 10px;
  margin: 7px 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  color: var(--text);
}
.partner__offers li + li::before {
  content: "·";
  margin-right: 10px;
  color: var(--acc, var(--rose-fushia));
}
.partner__addr {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  margin-top: 8px;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  text-decoration: none;
  transition: color var(--dur-med) var(--ease-out);
}
.partner__addr:hover { color: var(--acc, var(--rose-fushia)); }
.partner__addr svg { flex: none; }
/* Plus besoin d'empiler sur petit ecran : une vignette de 76px et son
   texte tiennent cote a cote meme a 390px. On resserre seulement. */
@media (max-width: 560px) {
  .partner { gap: var(--sp-4); padding: var(--sp-4) 0; }
  .partner__logo { width: 84px; height: 58px; }
}

/* ── Surtitre du hero de l'accueil ─────────────────────────────
   « Les Massiliades × Le Tremplin », en Botch et en rose.
   ⚠ Le signe × est ABSENT de Botch : il est dessine par la police de
   repli. C'est le seul caractere du site dans ce cas, et il passe
   inapercu parce qu'il est simple — mais ne pas s'etonner de le voir
   d'un autre dessin que les lettres qui l'entourent.
   La taille est reduite sous 480px : a 1,15rem le surtitre se cassait
   en deux lignes des 360px, mesure. */
.hero-kicker { font-size: clamp(1.15rem, 2.4vw, 1.6rem); }
@media (max-width: 480px) {
  .hero-kicker { font-size: clamp(0.95rem, 4.4vw, 1.15rem); }
}

/* ── Bande de logos partenaires (Tremplin) ─────────────────────
   Reprend le pied de l'affiche du Tremplin. Les fichiers sont ceux de
   la page partenaires, deja adaptes au fond noir. */
.bande-logos {
  margin-top: var(--sp-8);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--border);
}
.bande-logos__titre {
  margin: 0 0 var(--sp-5);
  font-weight: var(--fw-bold);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  text-align: center;
  color: var(--acc, var(--rose-fushia));  /* l accueil n a pas de --acc : il retombe sur le rose du site */
}
/* TOUT est centre : le surtitre comme la rangee de logos. Le defaut
   d'origine n'etait pas le centrage lui-meme mais son INCOHERENCE — le
   titre a gauche et les logos au milieu. Les deux partagent maintenant
   le meme axe, et la bande reste centree quelle que soit la largeur
   d'ecran puisqu'elle vit dans la colonne bornee par --page-max. */
.bande-logos__rangee {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(18px, 4vw, 46px);
}
.bande-logos__rangee a {
  position: relative;
  display: block;
  width: clamp(66px, 16vw, 100px);
  height: clamp(38px, 9vw, 56px);
  opacity: .8;
  transition: opacity var(--dur-med) var(--ease-out);
}
.bande-logos__rangee a:hover,
.bande-logos__rangee a:focus-visible { opacity: 1; }
/* Meme lecon que sur la page partenaires : en absolu avec inset, la
   boite de l'image vaut exactement celle du lien, sans pourcentage de
   hauteur a resoudre — sinon les logos CARRES debordent de 36px. */
.bande-logos__rangee img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* Sous 560px, cinq logos en ligne cassaient en 4 + 1 : le dernier se
   retrouvait seul sur sa rangee. Une grille de trois colonnes donne
   3 + 2, qui se tient. */
@media (max-width: 560px) {
  .bande-logos__rangee {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    justify-items: center;
    gap: var(--sp-5) var(--sp-4);
  }
  .bande-logos__rangee a { width: 100%; }
}

/* ── Doodles décoratifs (étoiles, notes, clé de sol, mascottes) ──
   .doodle : forme noire utilisée comme masque, teintée via --dc.
   .doodle-img : mascotte déjà colorée, posée telle quelle.
   Réglages par élément (inline) : --dm masque, --dc couleur,
   --dr rotation, --do opacité, --dd déphasage du flottement. */
.has-doodles { position: relative; isolation: isolate; }
.doodle,
.doodle-img {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  user-select: none;
  rotate: var(--dr, 0deg);
  opacity: var(--do, 1);
  animation: doodle-float 7s ease-in-out infinite;
  animation-delay: var(--dd, 0s);
}
.doodle {
  background-color: var(--dc, var(--rose-fushia));
  -webkit-mask: var(--dm) center / contain no-repeat;
  mask: var(--dm) center / contain no-repeat;
}
@keyframes doodle-float {
  0%, 100% { translate: 0 0; }
  50% { translate: 0 -8px; }
}
@media (prefers-reduced-motion: reduce) {
  .doodle, .doodle-img { animation: none; }
}
/* Sur petit écran les marges disparaissent : on retire le décor qui
   y était posé, sinon il vient recouvrir le texte.
   Exception faite des .doodle--front : ceux-là ne sont pas dans une
   marge mais calés sur l'angle d'un bloc, et un angle existe à toute
   largeur. Ils restent donc visibles, simplement réduits. */
@media (max-width: 760px) {
  .doodle:not(.doodle--front), .doodle-img { display: none; }
  .doodle--front { scale: .72; }

  /* Exception : les doodles poses DANS la pochette d'un artiste ne sont
     pas dans une marge. Ils flottent sur l'image, a l'interieur d'un
     cadre carre qui existe a toute largeur, et ne peuvent donc pas
     mordre sur un texte. On les garde, simplement reduits. */
  .detail__art-face .doodle { display: block; scale: .78; }

  /* L'origine de la réduction est calée sur l'angle LIBRE de chaque
     étoile : elle se réduit donc vers le dehors, et sa moitié
     intérieure recule au lieu de mordre sur le texte. Nécessaire ici,
     car le rembourrage des cases tombe à 16px sur ces écrans — réduire
     par le centre laissait 78px² d'étoile sur un paragraphe. */
  .principe .doodle--tl { transform-origin: top left; }
  .principe .doodle--tr { transform-origin: top right; }
  .principe .doodle--bl { transform-origin: bottom left; }
  .principe .doodle--br { transform-origin: bottom right; }
  .principe .doodle--t  { transform-origin: top center; }

  /* La carte du formulaire longe le bord de l'écran : ses étoiles
     doivent au contraire RENTRER, sinon elles se font rogner. D'où une
     réduction plus forte, par le centre, que les 34px de rembourrage
     de la carte absorbent sans que le texte soit touché.
     .62 et non .72 parce que ces étoiles sont inclinées : une étoile
     de 54px penchée à 14° occupe 66px de large, et c'est cette boîte-là
     qui dépassait de l'écran. */
  .ticket__bientot .doodle--front {
    transform-origin: center;
    scale: .62;
  }
}
/* Certains doodles sont posés à mi-hauteur, dans la marge droite que
   le texte vient occuper dès que la page rétrécit. Comme ils passent
   DERRIÈRE le texte (z-index -1), un doodle beige sous un paragraphe
   beige le rendait illisible bien avant le seuil des 760px.
   Ceux-là ne sortent qu'au-delà de 1000px. */
@media (max-width: 1000px) {
  .doodle--large { display: none; }
}
/* ── Rangee d'etoiles fines, petit ecran uniquement ─────────
   Sur mobile les doodles des marges disparaissent et la page perd
   son grain. Cette rangee le rend, juste au-dessus des tuiles
   d'artistes. Difference essentielle avec un .doodle : elle est
   DANS LE FLUX, pas en absolu — elle ne peut donc rien recouvrir,
   c'est ce qui la rend sure la ou les autres ne l'etaient pas.
   Reglages par etoile : --sm masque, --sc couleur, --sw largeur,
   --sr proportions, --srot rotation, --sd dephasage. */
.star-row { display: none; }
@media (max-width: 760px) {
  .star-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(16px, 6vw, 30px);
    margin-bottom: var(--sp-5);
  }
  .star-row span {
    display: block;
    width: var(--sw, 22px);
    aspect-ratio: var(--sr, 1);
    background-color: var(--sc, var(--beige));
    -webkit-mask: var(--sm) center / contain no-repeat;
    mask: var(--sm) center / contain no-repeat;
    rotate: var(--srot, 0deg);
    animation: doodle-float 7s ease-in-out infinite;
    animation-delay: var(--sd, 0s);
  }
}
@media (prefers-reduced-motion: reduce) {
  .star-row span { animation: none; }
}

/* Variante qui passe DEVANT le contenu au lieu de derrière. Réservée
   aux doodles posés à cheval sur le bord d'un bloc opaque : sans elle,
   la moitié qui recouvre le bloc disparaîtrait sous son fond.
   À n'utiliser que calé sur un angle, jamais au-dessus d'un texte. */
.doodle--front { z-index: 1; }

/* ── Page Tremplin ────────────────────────────────────────────
   Le second concert : gratuit, en plein air. Il porte le vert de
   la charte, la couleur la plus « dehors » de la palette. */
.tremplin-page { --acc: var(--vert-pale); }
.tremplin-page .navbar__links li.is-active a { color: var(--vert-pale); background: var(--vert-16); }
.tremplin-page .navbar__links li.is-active a:hover { background: var(--vert-16); }

/* ── Hero du Tremplin ─────────────────────────────────────────
   Même principe que le hero de l'accueil : une photo de concert
   derrière le texte, assombrie pour que le titre reste lisible, et
   un halo coloré au-dessus. Deux écarts assumés :

   1. Le voile est beaucoup plus léger qu'à l'accueil (.55 → .88 ici,
      .78 → .92 là-bas). La photo de l'accueil est mesurée à 70/255
      de luminance, celle-ci à 27 : le voile de l'accueil la
      ramènerait à 17, soit la couleur exacte du fond de page — elle
      disparaîtrait. Le fichier tremplin7-hero.webp est en plus déjà
      remonté en luminosité à la conversion.
   2. Le halo est vert et non rose : c'est l'accent de cette page.

   Le débord pleine largeur reprend l'idiome de .detail--bg::before.
   Les deux couches sont en z-index -2 pour passer sous les doodles
   (-1), qui continuent donc de flotter par-dessus la photo. */
.tremplin-hero {
  position: relative;
  isolation: isolate;
  padding: var(--sp-6) 0 var(--sp-8);

  /* Voile par défaut : uniforme et dense. Le paragraphe fait 58ch de
     large — soit 80 % de la page à 860px, et encore 69 % à 1000px. En
     dessous de 1200px il n'existe donc pas de « côté droit » libre, et
     tout voile dégradé laisse des lignes sous le seuil de contraste
     (mesuré : 4.06:1 à 860px). Il est redéfini plus bas pour les
     grands écrans, où la photo peut enfin respirer à droite. */
  /* ALLEGE avec le changement de photo. Les valeurs precedentes
     (0.88/0.82/0.93) etaient calibrees sur tremplin7-hero, qui portait
     des projecteurs blancs : luminance mediane 46,7/255 et 5,7 % de
     pixels au-dessus de 200. fond-groupe-rose est bien plus sombre —
     mediane 8,3/255, 0,01 % de pixels clairs — et le meme voile
     effacait purement et simplement le rose. */
  /* Remonte apres coup : le cadrage a 0% et la reduction des tailles
     ont amene la photo, plus claire a gauche, sous la date et le bouton
     — tous deux en vert #B8E06F. Mesure a 3,79 et 4,34 : sous le seuil.
     A 0,50/0,42 ils repassent au-dessus sans que la photo redevienne le
     mur noir du depart. */
  --hero-veil: linear-gradient(180deg, rgba(16, 16, 17, 0.50) 0%, rgba(16, 16, 17, 0.42) 50%, rgba(16, 16, 17, 0.76) 100%);

  /* ZOOM DE LA PHOTO. Elle est en portrait (2400 x 3394) et le hero est
     large : en `cover` elle deborde en HAUTEUR seulement, la largeur
     tombant pile — et background-position-x n'a alors AUCUN effet. Il
     faut donc la zoomer au-dela de cover pour pouvoir la decaler.
     ⚠ Mais 130% ne couvre plus sur telephone : mesure, le hero fait
     739px de haut a 360px de large quand la photo n'en ferait que 662.
     Le zoom est donc reserve aux ecrans ou il couvre encore. */
  --hero-zoom: cover;

  /* CADRAGE HORIZONTAL. Sur telephone la boite est plus haute que large
     en proportion : `cover` met alors l'image a l'echelle sur la HAUTEUR
     et elle deborde horizontalement — 118px a 390px de large, 163px a
     360px. background-position-x y a donc un effet, contrairement aux
     grands ecrans ou le debord est vertical.
     A 0%, la fenetre se cale sur le bord GAUCHE de la photo : le
     guitariste apparait en entier. A 35% il etait coupe. */
  --hero-x: 0%;
}

/* Sur telephone, le titre occupait presque toute la largeur et venait
   mordre sur la gouttiere : cale a gauche, il paraissait rogne a droite.
   Tout le bloc passe au centre, ou il respire des deux cotes. */
@media (max-width: 760px) {
  .tremplin-hero { text-align: center; }
  .tremplin-hero p { margin-inline: auto; }


  /* La mascotte du haut reste visible sur telephone. Elle ne peut pas
     rester en absolu : dans une marge qui n'existe plus, elle passerait
     sur le titre. On la remet DANS LE FLUX, centree au-dessus du titre —
     elle ne peut alors rien recouvrir, quelle que soit la largeur.
     Sa largeur vient du style inline de la page (130px), qui l'emporte
     sur cette feuille : inutile de la redeclarer ici, ce serait une
     ligne sans effet. */
  .tremplin-hero .doodle-img {
    display: block;
    position: static;
    z-index: auto;
    margin: 0 auto var(--sp-4);
    rotate: 0deg;
  }
}

/* Au-dela de 640px, la photo zoomee couvre largement le hero : mesure,
   elle fait 1412px de haut a 768px de large pour un hero de 516px. */
@media (min-width: 640px) {
  /* Au-dela de 640px, le debord redevient vertical : c'est le zoom qui
     recree du jeu horizontal, et 35% cadre alors la chanteuse a droite
     du texte sans couper le bassiste derriere le titre. */
  .tremplin-hero { --hero-zoom: 130% auto; --hero-x: 35%; }
}

@media (min-width: 1200px) {
  .tremplin-hero {
    --hero-veil:
      /* Voile HORIZONTAL, dense à gauche où court le texte, léger à
         droite où la photo se découvre. Mesuré : sans lui, le pixel de
         fond le plus clair sous le paragraphe tombait à 1.94:1 — un
         projecteur blanc sous du beige. */
      /* ALLEGE avec le changement de photo. Les valeurs precedentes
         (0.94 a gauche, 0.42 a droite, plus un voile vertical a 0.45)
         cumulaient plus de 96 % d'opacite sous le titre : elles etaient
         calibrees sur les projecteurs blancs de tremplin7-hero. La
         nouvelle photo, deja rose et bien plus sombre, n'en demande pas
         autant — et le rose disparaissait sous l'ancien voile.
         Contraste re-mesure apres allegement, voir plus bas. */
      linear-gradient(100deg, rgba(16, 16, 17, 0.50) 0%, rgba(16, 16, 17, 0.40) 40%, rgba(16, 16, 17, 0.18) 72%, rgba(16, 16, 17, 0.04) 100%),
      /* Voile vertical, plus léger : il ne sert plus qu'à décrocher la
         photo de la nav en haut et à la fondre dans la page en bas. */
      linear-gradient(180deg, rgba(16, 16, 17, 0.10) 0%, rgba(16, 16, 17, 0.04) 42%, rgba(16, 16, 17, 0.62) 100%);
  }
}
.tremplin-hero::before {
  content: "";
  position: absolute;
  z-index: -2;
  /* plein cadre : on sort de la colonne centrée jusqu'aux bords */
  left: calc(50% - 50vw);
  width: 100vw;
  /* on remonte jusque sous la barre de navigation */
  top: calc(var(--sp-8) * -1);
  bottom: 0;
  /* fond-groupe-rose.webp est la photo de l'affiche, DEJA en duotone
     rose dans le fichier : aucun blend a faire ici, contrairement a la
     section « Le principe » qui, elle, colorise une photo neutre.
     Le fichier fourni pesait 26,7 Mo en PNG ; il est livre en WebP a
     1600px de large, soit 100 Ko — 261 fois plus leger.
     Cadrage bas (center 62%) : les musiciens sont dans le tiers
     inferieur de l'image, un cadrage centre ne montrait que le noir
     du haut de scene. */
  background:
    var(--hero-veil),
    url("../img/fond-groupe-rose.webp") var(--hero-x) 52% / var(--hero-zoom) no-repeat;
  /* la photo se dissout vers le bas au lieu de s'arrêter net */
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
}
.tremplin-hero::after {
  content: "";
  position: absolute;
  z-index: -2;
  width: min(760px, 92vw);
  aspect-ratio: 1;
  top: -24%;
  left: 50%;
  transform: translateX(-50%);
  background: radial-gradient(circle, rgba(184, 224, 111, 0.18), transparent 62%);
  filter: blur(24px);
  pointer-events: none;
}
/* Le voile étant léger sur grand écran, la photo reste contrastée sous
   le texte : une ombre portée discrète garantit la lecture au-dessus
   des projecteurs les plus clairs. */
.tremplin-hero h1,
.tremplin-hero p {
  text-shadow: 0 2px 18px rgba(16, 16, 17, 0.75);
}

/* ── Titre de l'affiche ────────────────────────────────────────
   « Le Tremplin » puis « musical », sur deux lignes, comme l'affiche
   du Tremplin. Interligne serrée : les deux lignes doivent former un
   bloc, pas deux titres empilés. */
.tremplin-hero__titre {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-hero);
  line-height: .82;
  letter-spacing: var(--ls-display);
  color: var(--text);
}
.tremplin-hero__titre span { display: block; }


/* La date sous le titre, en vert, comme sur l'affiche. Elle est en
   Botch : « sam. 10 oct. 2026 » n'a ni accent ni apostrophe, rien à
   contourner. */
.tremplin-hero__quand {
  margin: var(--sp-4) 0 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.3rem, 4.4vw, 2.1rem);
  line-height: 1;
  letter-spacing: var(--ls-display);
  color: var(--vert-pale);
}

/* Taille du paragraphe de presentation. Elle etait posee en style
   INLINE dans tremplin.html, ce qui la rendait intouchable : un style
   inline bat toute feuille de style, media query comprise. */
.tremplin-hero__texte { font-size: var(--fs-lead); }

/* ⚠ CETTE MEDIA QUERY DOIT RESTER LA DERNIERE des regles du hero.
   Placee plus haut — avec les autres reglages telephone — elle etait
   ECRASEE par les regles de base : a specificite egale, c'est la
   derniere ecrite qui gagne, media query ou pas. Verifie deux fois :
   les tailles n'avaient pas bouge d'un pixel.

   Le hero etait trop gros sur telephone : mesure a 390px, le paragraphe
   sortait a 22px sur 8 lignes — 216px de haut a lui seul — et le titre
   a 48,75px. */
@media (max-width: 760px) {
  .tremplin-hero__titre { font-size: clamp(2.1rem, 10.5vw, 2.9rem); }
  .tremplin-hero__quand { font-size: clamp(1.05rem, 4.4vw, 1.3rem); }
  .tremplin-hero__texte { font-size: var(--fs-body); }
}

/* ── Faits pratiques du Tremplin ───────────────────────────────
   Une grande photo à gauche, les trois faits empilés à droite.
   La liste .factlist reste celle de la billetterie : on ne redéfinit
   son sens d'empilement que dans ce contexte-ci. */
.facts {
  display: grid;
  /* carrousel · faits — la mascotte occupait une troisième colonne,
     elle a été retirée. Le carrousel reste volontairement plafonné bas
     et les gouttières resserrées : à pleine taille il étranglait la
     colonne de droite et « Gratuit, ouvert à tous » se cassait en deux
     lignes. */
  grid-template-columns: minmax(240px, 420px) 1fr;
  gap: clamp(20px, 3vw, 44px);
  align-items: center;
  margin: var(--sp-7) 0 var(--sp-8);
}
/* ── Faits pratiques, variante nue ─────────────────────────────
   ⚠ Les sélecteurs chaînent .factlist.factlist--nu et non le seul
   .factlist--nu : les règles de base .factlist sont déclarées plus
   bas dans ce fichier, et à spécificité égale c'est la dernière qui
   l'emporte. Sans le chaînage, les pastilles encadrées revenaient et
   les libellés reprenaient leur beige.

   Plus de pastilles encadrées : une étoile à gauche, le libellé en
   Botch, la valeur en Helvetica dessous. Rien qu'un rythme, sans
   cadre ni fond.

   Toutes les couleurs passent par --acc : le composant sort donc vert
   sur le Tremplin et rose sur la billetterie sans être dupliqué. Seule
   la disposition change d'une page à l'autre, plus bas. */
.factlist.factlist--nu {
  display: grid;
  gap: var(--sp-6);
  margin: var(--sp-6) 0 var(--sp-8);
}
/* Chaque fait est une petite grille de deux colonnes : l'icône à
   gauche sur toute la hauteur, le libellé et la valeur empilés à
   droite. L'icône étant une CASE DE GRILLE et non un élément flottant,
   elle ne peut pas passer sous le texte — c'est le point qui distingue
   ces icônes-ci des .doodle du reste du site, posés en absolu avec un
   z-index négatif. */
.factlist.factlist--nu > div {
  display: grid;
  grid-template-columns: var(--ico-size, 48px) 1fr;
  column-gap: var(--sp-4);
  /* 2px entre le libelle en Botch (24px sur telephone) et sa valeur :
     mesure, c'etait le passage le plus serre du site. */
  row-gap: 6px;
  align-items: center;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 0;
}
.factlist.factlist--nu > div::before {
  content: "";
  grid-column: 1;
  grid-row: 1 / span 2;   /* l'icône couvre le libellé ET la valeur */
  width: var(--ico-size, 48px);
  height: var(--ico-size, 48px);
  /* forme noire teintée dans l'accent de la page, comme les doodles */
  background-color: var(--acc, var(--rose-fushia));
  -webkit-mask: var(--ico) center / contain no-repeat;
  mask: var(--ico) center / contain no-repeat;
}
.factlist.factlist--nu > div[data-ico="etoile"]::before { --ico: url("../img/deco/star6-filled.webp"); }

/* Le libellé porte la police d'affichage : il n'est plus un petit
   surtitre en capitales espacées mais le mot qui accroche l'œil.
   D'où la suppression des capitales et de l'interlettrage, que Botch
   ne supporte pas — ses lettres sont déjà larges et pleines.
   ⚠ Les libellés doivent rester SANS ACCENT : Botch les avale
   silencieusement (« Entrée » s'y afficherait « Entree », ce qui
   passe pour une faute et non pour un défaut de police). */
.factlist.factlist--nu dt {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.5rem, 2.6vw, 2.125rem);
  line-height: 1;
  letter-spacing: var(--ls-display);
  text-transform: none;
  color: var(--acc, var(--rose-fushia));
}
/* La valeur reste en Helvetica : elle peut donc porter ses accents
   sans réserve. */
.factlist.factlist--nu dd,
.factlist.factlist--nu dd a {
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: var(--fs-lead);
  line-height: var(--lh-body);
  letter-spacing: 0;
  color: var(--text);
}
.factlist.factlist--nu dd a:hover { color: var(--acc, var(--rose-fushia)); }

/* Tremplin : la liste tient dans une colonne étroite à côté du
   carrousel, elle reste donc sur une seule colonne. */
.facts .factlist--nu { margin: 0; }

/* Billetterie : la liste occupe toute la largeur de la page, sur une
   seule rangée. En grille à colonnes égales, l'adresse se cassait en
   deux lignes pendant que le nom de la salle laissait la moitié de sa
   colonne vide. En flex, chaque fait prend la largeur de son contenu
   et la rangée tient d'un bloc — puis se replie d'elle-même quand
   l'écran se resserre. */
.bill-page .factlist.factlist--nu {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-6) clamp(24px, 5vw, 64px);
}

@media (max-width: 860px) {
  .facts { grid-template-columns: 1fr; }
  /* seul sur sa ligne, le carrousel n'a plus besoin d'être aussi haut */
  .carousel { aspect-ratio: 3 / 2; }
  .facts .factlist--nu { gap: var(--sp-5); }
  .factlist.factlist--nu > div { --ico-size: 40px; }
}

/* ── Carrousel de photos ───────────────────────────────────────
   Les photos glissent horizontalement dans un cadre qui les rogne.
   Le défilement est piloté par assets/js/carousel.js, qui ne fait que
   poser une translation sur .carousel__track — toute la mise en forme
   est ici. Sans JavaScript, la première photo reste affichée : le bloc
   ne se casse pas, il devient simplement fixe. */
.carousel {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--r-lg);
  overflow: hidden;
  /* même liseré que le reste : sur la scène noire une photo de nuit
     n'a pas de bord visible */
  box-shadow: var(--shadow-sm), 0 0 0 1px var(--border);
}
.carousel__track {
  display: flex;
  height: 100%;
  transition: transform var(--dur-slow) var(--ease-out);
}
.carousel__slide {
  flex: 0 0 100%;
  margin: 0;
  height: 100%;
}
.carousel__slide img { width: 100%; height: 100%; object-fit: cover; }

/* Flèches : le rond des liens de streaming (.rnd), mais posé sur une
   photo — d'où le fond sombre translucide, sans quoi le trait beige
   disparaît sur les projecteurs clairs. */
.carousel__arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  border: 1.5px solid var(--beige-16);
  background: rgba(16, 16, 17, 0.55);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--beige);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.carousel__arrow:hover {
  background: var(--acc, var(--rose-fushia));
  border-color: var(--acc, var(--rose-fushia));
  color: var(--gris-fonce);
}
.carousel__arrow--prev { left: 12px; }
.carousel__arrow--next { right: 12px; }

/* Puces : la cible tactile fait 24px, le point n'en fait que 8.
   Un point de 8px serait impossible à viser au doigt. */
.carousel__dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 12px;
  display: flex;
  justify-content: center;
  gap: 4px;
}
.carousel__dot {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.carousel__dot::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--beige);
  opacity: .45;
  /* la photo passe dessous : sans ombre, le point disparaît sur les
     zones claires */
  box-shadow: 0 1px 4px rgba(0, 0, 0, .7);
  transition: opacity var(--dur-fast), background var(--dur-fast);
}
.carousel__dot:hover::before { opacity: .75; }
.carousel__dot.is-active::before {
  background: var(--acc, var(--rose-fushia));
  opacity: 1;
}

/* Le site n'a pas de style de focus général — ces trois boutons sont
   de vraies commandes, ils en méritent un. */
.carousel__arrow:focus-visible,
.carousel__dot:focus-visible {
  outline: 2px solid var(--acc, var(--rose-fushia));
  outline-offset: 2px;
}

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

/* ── Section « Le principe » ───────────────────────────────────
   La photo du public passe en fond plein cadre derrière la section,
   avec le même débord que le hero. Le voile est ici beaucoup plus
   dense : tremplin5 est de loin la plus claire des quatre (99.7 de
   luminance moyenne contre 27 pour celle du hero), ses projecteurs
   saturent, et le surtitre vert doit tenir par-dessus. */
.principe { padding: var(--sp-7) 0 var(--sp-8); }
/* Le surtitre respire davantage sous le titre en Botch — même parti
   pris que .section-title--display, dont le surtitre reçoit lui aussi
   une marge supplémentaire. Réglé ici seulement : les autres pages
   gardent leur écart d'origine. */
.principe .section-title__eyebrow { margin-bottom: var(--sp-3); }
.principe::before {
  content: "";
  position: absolute;
  z-index: -2;
  left: calc(50% - 50vw);
  width: 100vw;
  inset-block: 0;
  /* MEME PHOTO QUE LE HERO. Elle est deja en duotone rose dans le
     fichier : les trois couches de colorisation qui vivaient ici —
     aplat rose en blend `color` et voile blanc en `screen` pour
     rattraper une photo neutre et sombre — n'ont plus lieu d'etre.
     Il ne reste que le voile de lecture et la photo. */
  /* Voile allege : de 0,74/0,66/0,90 a ces valeurs. Le texte de la
     section est pose a meme la photo, sans case ni surlignage, donc
     tout allegement se paie en lisibilite — verifie apres coup. */
  background:
    linear-gradient(180deg, rgba(16, 16, 17, 0.54) 0%, rgba(16, 16, 17, 0.46) 45%, rgba(16, 16, 17, 0.82) 100%),
    url("../img/fond-groupe-rose.webp") center 42% / cover no-repeat;
  /* la photo naît et meurt en fondu : la section n'a pas de bord franc */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 84%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 84%, transparent 100%);
}
/* Les étapes du parcours d'un groupe : c'est une vraie séquence
   (on s'inscrit, puis on joue, puis on gagne), la numérotation
   porte donc une information et n'est pas décorative — d'où un
   compteur de liste et non trois chiffres écrits à la main.

   PLUS DE CASES. Elles ont disparu à la demande de Hugues : ni cadre,
   ni fond, ni flou, ni pastille ronde. Il reste le chiffre, en gros et
   en vert, et le texte à côté. La photo en duotone passe donc derrière
   le texte nu — c'est pourquoi le voile de .principe::before compte
   autant, et pourquoi les paragraphes remontent en --text au lieu de
   --text-muted : mesuré, le gris atténué tombait sous le seuil de
   lisibilité une fois posé sur la photo. */
.steps { list-style: none; counter-reset: etape; margin: var(--sp-6) 0 0; padding: 0; display: grid; gap: var(--sp-6); }
.steps li {
  counter-increment: etape;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  /* colonne seulement : un gap sur les RANGEES viendrait s'ajouter a la
     marge du <h3> et creuserait un trou entre le titre et son texte. */
  column-gap: var(--sp-4);
  row-gap: 0;
  padding: 0;
  border: 0;
  background: none;
}
/* ⚠ Le <li> compte TROIS enfants de grille — le ::before du chiffre, le
   <h3> et le <p> — pour deux colonnes. Sans les placements ci-dessous,
   la deuxieme rangee recevait le <p> dans la COLONNE DU CHIFFRE : le
   titre partait a droite et le texte revenait a gauche, sous le chiffre.
   Le chiffre est donc explicitement cale sur la colonne 1 et etendu sur
   toutes les rangees ; le titre et le texte occupent la colonne 2. */
.steps li::before {
  content: counter(etape);
  grid-column: 1;
  grid-row: 1 / -1;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.6rem, 8vw, 4rem);
  line-height: .8;
  letter-spacing: var(--ls-display);
  color: var(--vert-pale);
  /* le chiffre est large et plein : une largeur minimale garde les
     trois textes alignes entre eux, que le chiffre soit 1 ou 3 */
  min-width: 1.1em;
  text-align: center;
  text-shadow: 0 2px 16px rgba(16, 16, 17, .75);
}
.steps h3 { grid-column: 2; }
.steps p  { grid-column: 2; }
/* Les titres passent en Botch. ⚠ Verifie caractere par caractere : les
   trois n'ont ni apostrophe, ni deux-points, ni barre oblique — que
   Botch dessinerait en etoile. Le troisieme portait « deuxieme », dont
   l'accent aurait ete avale et se serait lu comme une faute : il a ete
   reformule en « second ». Toute reecriture de ces titres doit repasser
   ce controle. Botch etant large et pleine, la taille monte d'un cran
   et l'interlettrage se resserre. */
/* Titre en Botch ET en vert. Le chiffre l'est aussi : c'est le vert qui
   structure la section, le beige etant reserve au texte courant. */
.steps h3 {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.15rem, 3.2vw, 1.5rem);
  line-height: 1;
  letter-spacing: var(--ls-display);
  color: var(--vert-pale);
  text-shadow: 0 1px 12px rgba(16, 16, 17, .8);
}
/* Le texte repasse sur la photo, sans surlignage : l'ombre portee qui
   le detache du fond redevient necessaire. */
.steps p {
  margin: 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text);
  max-width: 62ch;
  text-shadow: 0 1px 12px rgba(16, 16, 17, .8);
}

/* ── Formulaire Brevo ─────────────────────────────────────────
   Le balisage et le script viennent de Brevo : c'est leur code qui
   valide et envoie, on ne reprend que l'habillage pour qu'il tienne
   sur la scène noire au lieu d'y poser un rectangle blanc.
   Les !important sont nécessaires : Brevo pose ses couleurs en
   style inline, qu'aucune feuille externe ne peut battre autrement. */
.brevo {
  /* Accent du formulaire : vert par défaut (le Tremplin). Chaque page
     peut le redéfinir — voir .bill-page .brevo, en rose. */
  --bv: var(--vert-pale);
  --bv-soft: var(--vert-16);
  --bv-ink: var(--gris-fonce);
  max-width: 560px;
  margin: var(--sp-4) auto 0;
  background: transparent !important;
  text-align: left !important;
  /* Brevo pose « padding: 32px 12px » sur .sib-form, ce qui décalait
     la carte visible de 12px sur les côtés et de 32px en haut et en
     bas par rapport à ce bloc. Toute position calculée sur ce bloc
     tombait donc à côté de la carte. On l'annule entièrement : le
     bloc et la carte coïncident, et le rembourrage intérieur de la
     carte (34px, posé sur #sib-container) suffit largement. */
  padding: 0 !important;
}
.brevo #sib-container {
  max-width: 100% !important;
  padding: clamp(22px, 4vw, 34px) !important;
  background: var(--surface-raised) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--r-xl) !important;
  text-align: left !important;
}
.brevo .sib-form-block { padding: 0 !important; }
.brevo .form__entry { margin-bottom: var(--sp-4); }
.brevo .entry__label {
  display: block;
  margin-bottom: 6px;
  font-family: var(--font-body) !important;
  font-size: var(--fs-sm) !important;
  font-weight: var(--fw-bold) !important;
  color: var(--text) !important;
}
.brevo .entry__label[data-required]::after { content: " *"; color: var(--bv); }
.brevo .input,
.brevo select.input {
  width: 100%;
  padding: 13px 18px !important;
  border: 1.5px solid var(--border-strong) !important;
  border-radius: var(--r-pill) !important;
  background: var(--stage) !important;
  color: var(--text) !important;
  font-family: var(--font-body) !important;
  font-size: 1rem !important;
  box-shadow: none !important;
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.brevo .input::placeholder { color: var(--beige-dim) !important; opacity: .5; }
.brevo .input:hover { border-color: var(--text-muted) !important; }
.brevo .input:focus,
.brevo .input:focus-visible {
  outline: none !important;
  border-color: var(--bv) !important;
  box-shadow: 0 0 0 3px var(--bv-soft) !important;
}
/* Brevo pose un fond BLANC et une bordure grise sur les conteneurs
   de champs. Sur la scène noire, ça dessinait un rectangle clair
   derrière chaque pilule : on les rend transparents. */
.brevo .entry__field,
.brevo .sib-sms-select__number-input__overlay {
  background: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 0 !important;
}

/* ── Champ téléphone ──
   Brevo remplace le <select> par son propre composant : un bouton
   pays à gauche, puis indicatif + numéro à droite. Il arrive en
   blanc sur blanc avec un texte noir — donc invisible ici. */
.brevo .sib-sms-input { display: flex; gap: var(--sp-2); }
.brevo .sib-sms-input .entry__field:first-child { flex: 0 0 auto; }
.brevo select.input { padding-right: 34px !important; }
.brevo .sib-sms-select { display: flex; gap: var(--sp-2); align-items: stretch; }
.brevo .sib-sms-select__title,
.brevo .sib-sms-select__number-input {
  border: 1.5px solid var(--border-strong) !important;
  border-radius: var(--r-pill) !important;
  background: var(--stage) !important;
  color: var(--text) !important;
}
.brevo .sib-sms-select__title {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 16px !important;
  cursor: pointer;
}
.brevo .sib-sms-select__label-text { font-family: var(--font-body); font-size: var(--fs-sm); color: var(--text); }
.brevo .sib-sms-select__number-input { flex: 1; display: flex; align-items: center; padding: 0 16px !important; }
.brevo .sib-sms-select__calling-code,
.brevo .sib-sms-select__phone-number {
  background: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  outline: none !important;
  font-family: var(--font-body) !important;
  font-size: 1rem !important;
}
.brevo .sib-sms-select__calling-code { width: 3.4em !important; padding: 13px 0 !important; color: var(--text-muted) !important; }
.brevo .sib-sms-select__phone-number { flex: 1; padding: 13px 6px !important; color: var(--text) !important; }
.brevo .sib-sms-select__phone-number::placeholder { color: var(--beige-dim) !important; opacity: .5; }
/* ── Formulaire Brevo sur telephone ────────────────────────
   Mesure a 375px de large : le selecteur de pays prenait 172px et ne
   laissait que 101px au numero — un champ plus etroit que son etiquette.
   On masque le nom du pays (le drapeau et l'indicatif +33 affiche juste
   a cote suffisent a l'identifier) et le numero recupere la place. Le
   reste de la carte est resserre d'un cran. */
@media (max-width: 560px) {
  .brevo #sib-container { padding: 18px !important; }
  .brevo .form__entry { margin-bottom: var(--sp-3); }
  .brevo .entry__label { font-size: var(--fs-sm); }
  .brevo .input,
  .brevo select.input { padding: 11px 16px !important; }
  /* Les deux champs passent l'un SOUS l'autre. Cote a cote, le
     selecteur de pays occupait 297px des 299 disponibles et ne laissait
     que 23px au numero. Empiles, chacun a toute la largeur.
     Le nom du pays reste affiche : c'est le seul repere qui dit quel
     indicatif sera reellement poste (voir l'episode du +93). */
  .brevo .sib-sms-input { flex-wrap: wrap; gap: 8px; }
  .brevo .sib-sms-select { flex-wrap: wrap; gap: 8px; }
  .brevo .sib-sms-select__title { flex: 1 1 100%; padding: 11px 14px !important; }
  .brevo .sib-sms-select__number-input { flex: 1 1 100%; min-width: 0; padding: 0 14px !important; }
  .brevo .sib-form-block__button { width: 100%; }
}

/* La liste des pays, construite au clic sur le bouton. Brevo la pose
   en enfant DIRECT de <body>, hors du formulaire : pas de préfixe
   .brevo ici, sinon le sélecteur ne l'atteint jamais. Elle arrive en
   blanc, et nos textes beiges y étaient illisibles. */
.sib-sms-select__list {
  background: var(--surface-raised) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--r-md) !important;
  box-shadow: var(--shadow-md) !important;
  /* la liste défile : sans ça le navigateur peint sa barre de
     défilement en clair, ce qui dessinait un liseré blanc au bord */
  color-scheme: dark;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
.sib-sms-select__list li {
  color: var(--text) !important;
  font-family: var(--font-body) !important;
  border-color: var(--border) !important;
}
.sib-sms-select__list li:hover,
.sib-sms-select__list li.is-selected { background: var(--beige-08) !important; }
.sib-sms-select__list input {
  background: var(--stage) !important;
  border: 1.5px solid var(--border-strong) !important;
  border-radius: var(--r-sm) !important;
  color: var(--text) !important;
}
.brevo .entry__specification {
  display: block;
  margin-top: 6px;
  font-family: var(--font-body) !important;
  font-size: var(--fs-xs) !important;
  color: var(--beige-dim) !important;
}
.brevo .entry__error {
  font-family: var(--font-body) !important;
  font-size: var(--fs-sm) !important;
  color: var(--rose-fushia) !important;
  background: transparent !important;
  border: 0 !important;
  padding: 4px 0 0 !important;
}
/* le bouton reprend exactement le bouton plein du site, dans
   l'accent de la page (vert sur le Tremplin, rose sur la billetterie) */
.brevo .sib-form-block__button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55em;
  margin-top: var(--sp-2);
  /* Plus petit et plus discret : contour plutot que pastille pleine,
     et un cran de moins en taille. Il reste un bouton net — c'est
     l'action principale du formulaire, l'effacer completement
     couterait des inscriptions. Il se remplit au survol. */
  padding: 10px 22px !important;
  border: 1.5px solid var(--bv) !important;
  border-radius: var(--r-pill) !important;
  background: transparent !important;
  color: var(--bv) !important;
  font-family: var(--font-body) !important;
  font-size: var(--fs-sm) !important;
  font-weight: var(--fw-bold) !important;
  cursor: pointer;
  transition: background var(--dur-med) var(--ease-out), color var(--dur-med) var(--ease-out);
}
/* Il se remplit au survol : discret au repos, franc au moment du geste. */
.brevo .sib-form-block__button:hover,
.brevo .sib-form-block__button:focus-visible {
  background: var(--bv) !important;
  color: var(--bv-ink) !important;
}
.brevo .sib-form-block__button:active { transform: scale(.98); }
/* messages de succès et d'erreur renvoyés par Brevo */
.brevo .sib-form-message-panel {
  max-width: 100% !important;
  margin-bottom: var(--sp-4);
  border-radius: var(--r-md) !important;
  font-family: var(--font-body) !important;
  font-size: var(--fs-sm) !important;
}
.brevo #success-message { background: var(--vert-16) !important; border-color: var(--vert-pale) !important; color: var(--vert-pale) !important; }
/* le succès reste vert partout : c'est un code couleur universel,
   pas l'accent de la page */
.brevo #error-message { background: var(--rose-12) !important; border-color: var(--rose-fushia) !important; color: var(--rose-fushia) !important; }
.brevo .sib-notification__icon { fill: currentColor; }

/* lien discret de désinscription, sous le formulaire */
.unsub {
  display: inline-block;
  margin-top: var(--sp-5);
  font-size: var(--fs-xs);
  color: var(--beige-dim);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.unsub:hover { color: var(--text-muted); }

/* ── Page Billetterie ─────────────────────────────────────────
   La page « Prendre sa place ». Elle a deux états, pilotés par le
   seul attribut data-etat posé sur la section .ticket :
     data-etat="bientot"  → le formulaire « préviens-moi »
     data-etat="ouverte"  → le lien vers la billetterie en ligne
   Changer ce mot dans billetterie.html suffit à basculer la page,
   sans JavaScript et sans rien supprimer. */
.bill-page { --acc: var(--rose-fushia); }
/* sur cette page, le bouton de la nav est déjà « ici » : on le pose
   en beige pour qu'il ne continue pas d'appeler au clic */
.bill-page .navbar__cta { background: var(--beige); color: var(--gris-fonce); }
.bill-page .navbar__cta:hover { color: var(--gris-fonce); transform: none; }

.ticket[data-etat="bientot"] .ticket__ouverte,
.ticket[data-etat="ouverte"] .ticket__bientot { display: none; }
/* Repère des étoiles posées à cheval sur la carte du formulaire.
   Le bloc est ramené à la largeur de la carte : les étoiles se calent
   alors sur ses bords RÉELS avec de simples décalages négatifs, au
   lieu d'un calcul à partir du centre — calcul qui devenait faux de
   12px de chaque côté à cause du rembourrage que Brevo pose sur
   .sib-form (voir le bloc .brevo plus haut).
   isolation:isolate cantonne leur z-index à ce bloc, sans quoi une
   étoile en z-index 1 pourrait passer devant la barre de navigation
   au défilement. */
.ticket__bientot {
  position: relative;
  isolation: isolate;
  max-width: 560px;
  margin-inline: auto;
}
.ticket__ouverte { display: flex; flex-direction: column; align-items: center; gap: var(--sp-4); text-align: center; }

/* faits pratiques : date, salle, adresse */
.factlist { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin: var(--sp-6) 0 var(--sp-8); }
.factlist > div {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 15px 26px;
  border-radius: var(--r-md);
  border: 1.5px solid var(--border);
  background: var(--surface-raised);
}
.factlist dt {
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--text-muted);
}
.factlist dd { margin: 0; font-size: var(--fs-body); font-weight: var(--fw-bold); color: var(--text); }
.factlist a { color: var(--text); text-decoration: none; transition: color var(--dur-fast); }
.factlist a:hover { color: var(--rose-fushia); }

/* ── Bloc « reste au courant » (billetterie) ──────────────────
   Le formulaire d'inscription Brevo, affiché tant que les places ne
   sont pas en vente. Il reprend l'habillage commun .brevo, mais en
   rose : c'est l'accent de cette page. */
.bill-page .brevo {
  --bv: var(--rose-fushia);
  --bv-soft: var(--rose-12);
  --bv-ink: var(--beige);
  margin-top: 0;
}

/* Le formulaire « devenir partenaire » suit l'accent de sa page, rose
   lui aussi. Sans cette surcharge il serait sorti vert, l'accent par
   defaut du bloc .brevo. */
.part-page .brevo {
  --bv: var(--rose-fushia);
  --bv-soft: var(--rose-12);
  --bv-ink: var(--beige);
}

/* Titre et chapeau posés en tête du formulaire. Ils remplacent les
   blocs de texte de Brevo, dont les styles arrivent en clair et en
   Roboto. */
.brevo__head { margin-bottom: var(--sp-5); }
.brevo__eyebrow {
  display: block;
  margin-bottom: var(--sp-3);
  font-weight: var(--fw-bold);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--bv);
}
/* Exception assumée : ce titre est en Helvetica et non en Botch.
   Botch n'a aucun caractère accentué et remplace l'apostrophe par
   une étoile — « dernières actus ! » y deviendrait « dernieres
   actus ! ». Un titre juste prime ici sur l'unité de police. */
.brevo__title {
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: clamp(1.5rem, 3vw, 2rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--text);
  text-wrap: balance;
}
.brevo__text {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-muted);
}

/* ── Les deux rendez-vous (accueil) ────────────────────────────
   Deux grandes affiches côte à côte, image au-dessus et brève
   description en-dessous. Chaque carte fixe son propre --acc :
   rose pour les Massiliades, vert pour le Tremplin. Tout ce qui
   colore la carte lit cette variable, la seule chose qui change
   d'une carte à l'autre. */
.duo {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--sp-9) var(--gutter);
}
.duo__head {
  align-items: center;
  text-align: center;
  /* Le surtitre a disparu : ce retrait rend au titre l'air qu'il
     occupait au-dessus, et le pose un peu plus bas. */
  margin-top: var(--sp-5);
  margin-bottom: var(--sp-7);
}
/* ── Etoiles autour du titre « 2 dates » ────────────────────
   Elles sont calees sur le TITRE lui-meme, pas sur la section : le h2
   passe en inline-block, sa boite epouse donc le texte et les etoiles
   restent a la meme distance des lettres a toute largeur.
   Ce ne sont pas des .doodle : elles echappent ainsi a la regle qui
   masque le decor sous 760px, et restent visibles sur telephone.
   Reglages par etoile : --sm masque, --sc couleur, --sw largeur,
   --sr proportions, --srot rotation, --sd dephasage. */
.duo__title {
  position: relative;
  display: inline-block;
}
.duo__star {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  width: var(--sw, 20px);
  aspect-ratio: var(--sr, 1);
  background-color: var(--sc, var(--beige));
  -webkit-mask: var(--sm) center / contain no-repeat;
  mask: var(--sm) center / contain no-repeat;
  rotate: var(--srot, 0deg);
  opacity: var(--so, 1);
  animation: doodle-float 7s ease-in-out infinite;
  animation-delay: var(--sd, 0s);
}
/* Sur telephone la gouttiere ne fait plus que 20px : les etoiles les
   plus ecartees sortiraient de l'ecran. On les rapproche et on les
   reduit d'un cran. */
@media (max-width: 560px) {
  .duo__star { scale: .8; }
}
@media (prefers-reduced-motion: reduce) {
  .duo__star { animation: none; }
}

.duo__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(24px, 4vw, 56px);
  align-items: start;
}

.duo__card { --acc: var(--rose-fushia); display: flex; flex-direction: column; }
.duo__card--vert { --acc: var(--vert-pale); }

/* Les deux affiches restent immobiles au survol : ni zoom, ni halo,
   ni soulevement. La photo se donne telle quelle. */
.duo__media {
  display: block;
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--r-xl);
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow-md);
}
.duo__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Voile bas discret : il assoit l'image sur le fond noir de la page
   et évite la coupure nette entre la photo et le texte. */
.duo__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(16, 16, 17, 0.55), transparent 45%);
  pointer-events: none;
}
.duo__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-2) 0;
}
.duo__when {
  font-weight: var(--fw-bold);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--acc);
}
.duo__name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-title);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  color: var(--text);
}
/* Le titre ne reagit pas au survol : meme couleur, meme position. */
.duo__name a { color: inherit; text-decoration: none; }
.duo__text {
  margin: 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-muted);
  max-width: 46ch;
}
/* Les liens des deux affiches ne sont plus des pastilles : juste le
   texte, dans la couleur de la carte. Ce sont les MEMES classes .btn--*
   que partout ailleurs — seul leur habillage est retire ici, la couleur
   reste donc pilotee par la variante. Les boutons du hero, eux, gardent
   leur contour : ce bloc ne descend pas jusqu'a eux.
   Le rembourrage vertical est invisible mais agrandit la zone tactile :
   sans lui, une ligne de texte n'offre qu'une vingtaine de pixels a
   viser au doigt. */
.duo__cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
  margin-top: var(--sp-3);
}
/* Les liens de ces deux affiches utilisent la classe commune
   .btn--texte : leur habillage et leurs couleurs sont definis
   une seule fois, plus haut, avec ceux du hero. */

/* Une colonne : les deux affiches se suivent. On plafonne la largeur
   de la carte plutôt que d'aplatir l'image — les deux photos sont des
   portraits, un recadrage en paysage y perdrait la scène. */
@media (max-width: 860px) {
  .duo { padding-block: var(--sp-8); }
  .duo__grid { grid-template-columns: 1fr; gap: var(--sp-8); }
  .duo__card { max-width: 480px; margin-inline: auto; width: 100%; }
  .duo__head { margin-bottom: var(--sp-6); }
}
