/* ═══════════════════════════════════════════════════════════
   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=5";
@import "colors.css?v=5";
@import "typography.css?v=5";
@import "spacing.css?v=5";

/* ── 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);
}
.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 {
  margin: 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); }
.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. Music Leader est
   un fichier transparent a l'encre claire, il ressort donc seul sur le
   fond sombre. France Pianos, lui, porte son propre fond blanc DANS le
   fichier : ce rectangle-la ne peut pas etre retire en CSS. */
.partner__logo {
  position: relative;
  width: 76px;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
}
.partner__logo img { max-width: 100%; max-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;
}
.partner__body { display: flex; flex-direction: column; gap: 6px; }
/* 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);
}
.partner__desc {
  margin: 0;
  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;
  gap: 4px 10px;
  margin: 2px 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: 4px;
  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: 60px; }
}

/* ── 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. */
  --hero-veil: linear-gradient(180deg, rgba(16, 16, 17, 0.80) 0%, rgba(16, 16, 17, 0.70) 50%, rgba(16, 16, 17, 0.90) 100%);
}

/* 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; }
}

@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. */
      linear-gradient(100deg, rgba(16, 16, 17, 0.92) 0%, rgba(16, 16, 17, 0.82) 40%, rgba(16, 16, 17, 0.38) 72%, rgba(16, 16, 17, 0.12) 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.45) 0%, rgba(16, 16, 17, 0.30) 42%, rgba(16, 16, 17, 0.86) 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;
  background:
    var(--hero-veil),
    url("../img/tremplin7-hero.webp") center / cover 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);
}

/* ── 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 · mascotte — le carrousel et la mascotte sont
     volontairement plafonnés bas, et les gouttières resserrées : à
     pleine taille ils étranglaient la colonne du milieu et « Gratuit,
     sans réservation » se cassait en deux lignes. */
  grid-template-columns: minmax(240px, 420px) 1fr auto;
  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);
  row-gap: 2px;
  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, « 103 rue Ferrari, 13005
   Marseille » se cassait en deux lignes pendant que « Le Makeda »
   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;
  background:
    linear-gradient(180deg, rgba(16, 16, 17, 0.88) 0%, rgba(16, 16, 17, 0.82) 45%, rgba(16, 16, 17, 0.94) 100%),
    url("../img/tremplin5-bg.webp") center / 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 cartes d'étapes laissent transparaître la photo au lieu de la
   masquer par trois rectangles opaques. Le flou est celui de la nav. */
.principe .steps li {
  background: color-mix(in srgb, var(--surface-raised) 80%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* 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. */
.steps { list-style: none; counter-reset: etape; margin: var(--sp-6) 0 0; padding: 0; display: grid; gap: var(--sp-4); }
.steps li {
  counter-increment: etape;
  position: relative;
  padding: var(--sp-5) var(--sp-5) var(--sp-5) 84px;
  border: 1.5px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface-raised);
}
.steps li::before {
  content: counter(etape);
  position: absolute;
  top: var(--sp-5);
  left: var(--sp-5);
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--vert-pale);
  color: var(--gris-fonce);
  font-family: var(--font-display);
  font-size: 1.4rem;
  line-height: 1;
}
.steps h3 { margin: 0 0 6px; font-size: var(--fs-body); font-weight: var(--fw-bold); color: var(--text); }
.steps p { margin: 0; font-size: var(--fs-body); line-height: var(--lh-body); color: var(--text-muted); }
@media (max-width: 520px) {
  .steps li { padding: 68px var(--sp-4) var(--sp-4); }
}

/* ── 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);
  padding: 15px 32px !important;
  border: 2px solid var(--bv) !important;
  border-radius: var(--r-pill) !important;
  background: var(--bv) !important;
  color: var(--bv-ink) !important;
  font-family: var(--font-body) !important;
  font-size: 1rem !important;
  font-weight: var(--fw-bold) !important;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-bounce), filter var(--dur-fast) var(--ease-out);
}
.brevo .sib-form-block__button:hover { transform: translateY(-2px); filter: brightness(1.06); }
.brevo .sib-form-block__button:active { transform: translateY(0) scale(.97); }
/* 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-2);
  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;
}
.duo__cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-2);
}

/* 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); }
}
