/* =============================================
   DONNA LEE AGENCY — STYLE.CSS
   Stack: HTML5/CSS3 Vanilla | No dependencies
   ============================================= */

/* Polices Google : chargées par un <link> dans index.html (plus rapide qu'un @import) */

/* ---- Variables ---- */
:root {
  --black: #000000;
  --white: #f7f6f2;   /* blanc cassé légèrement chaud (moins froid que le blanc pur) */
  --gray-1: #111111;
  --gray-2: #1a1a1a;
  --gray-3: #222222;
  --gray-4: #2a2a2a;
  --font-j: 'Plus Jakarta Sans', sans-serif;      /* réservée au LOGO « donna lee. » */
  --font-c: 'Bricolage Grotesque', sans-serif;    /* tout le reste : titres fins / mots forts gras */
  --ease-out: cubic-bezier(.16,1,.3,1);           /* départ vif, long atterrissage */
  --h: 60px;
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  font-size: 16px;
  scroll-snap-type: y mandatory;
}

body {
  background: var(--black);
  color: var(--white);
  font-family: var(--font-c);
  font-weight: 400;
  line-height: 1.6;
  cursor: none;
  overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
button { cursor: none; }

/* ---- Grain overlay (static, subtle) ---- */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  background-image: var(--grain);
  background-size: 256px 256px;   /* petit motif répété (même grain) : pas de filtre SVG de la taille de l'écran */
  opacity: 0.04;
  pointer-events: none;
  z-index: 9999;
}
/* Qualité allégée : ce voile couvre tout l'écran, y compris la vidéo : supprimé */
html.hp-lite body::after { display: none; }

/* ---- Page Transitions ---- */
body.page-out {
  opacity: 0;
  transition: opacity 300ms ease-out;
}
body.page-in {
  opacity: 0;
  transform: translateY(10px);
}
body.page-in.page-ready {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 500ms ease-out, transform 500ms ease-out;
}

/* ---- Custom Vinyl Cursor ---- */
#cursor {
  position: fixed;
  top: 0; left: 0;
  width: 18px; height: 18px;
  pointer-events: none;
  z-index: 99999;
  transform: translate(-50%, -50%);
}
/* Sur un élément cliquable, le curseur s'agrandit (classe posée par initCursor) */
#cursor svg { display: block; transition: transform 280ms var(--ease-out); }
#cursor.is-link svg { transform: scale(1.9); }
#cursor svg .c-stroke { transition: stroke 200ms; stroke: var(--white); }
#cursor svg .c-fill   { transition: fill 200ms;   fill: var(--white); }
#cursor.on-light svg .c-stroke { stroke: var(--black); }
#cursor.on-light svg .c-fill   { fill: var(--black); }

@media (hover: none) {
  #cursor { display: none; }
  body, button { cursor: auto; }
}

/* ---- Scroll Reveal ---- */
.reveal {
  opacity: 0;
  transition: opacity 600ms ease-out;
}
.reveal.visible { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transition: none; }
  body.page-in, body.page-in.page-ready { opacity: 1; transform: none; transition: none; }
  #cursor { display: none; }
  body { cursor: auto; }
  * { animation: none !important; transition: none !important; }
  
}

/* ---- Mot fort d'un titre : même police, épaisseur opposée (fin / gras) ---- */
.tx-fort { font-weight: 800; }

/* Affichage selon l'appareil (invitations « cliquer / toucher ») */
html.is-touch .only-mouse, html:not(.is-touch) .only-touch { display: none; }

/* =============================================
   HEADER
   ============================================= */
header {
  position: fixed;
  top: 0; left: 0; width: 100%;
  height: var(--h);
  /* Transparent : la vidéo passe derrière, un simple dégradé garde le menu
     lisible (plus de bande noire ni de flou recalculé à chaque image) */
  background: linear-gradient(to bottom, rgba(0,0,0,0.62), rgba(0,0,0,0)) no-repeat;
  border-bottom: 0;                       /* pas de bordure : le dégradé s'y répétait en fin trait sombre */
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 40px;
  z-index: 9000;
  transition: background-color 360ms ease, border-color 360ms ease;
}
header:not(.hdr-light) .logo-name,
header:not(.hdr-light) nav.dnav a,
header:not(.hdr-light) .lang-btn { text-shadow: 0 1px 10px rgba(0,0,0,0.55); }
header.hdr-light {
  background: rgba(247,246,242,0.94);
  border-bottom: 1px solid rgba(0,0,0,0.07);
}

.logo { display: flex; align-items: center; }

/* Logo texte « donna lee. » dans le header */
.logo-name {
  font-family: var(--font-j);
  font-weight: 800;
  font-size: 19px;
  letter-spacing: -0.04em;
  line-height: 1;
  text-transform: lowercase;
  color: var(--white);
  transition: color 200ms;
}
header.hdr-light .logo-name { color: var(--black); }

/* Point rond du logo (remplace le point carré de la police) */
.logo-dot {
  display: inline-block;
  width: 0.16em;
  height: 0.16em;
  margin-left: 0.03em;
  background: currentColor;
  border-radius: 50%;
  vertical-align: baseline;
}

/* Desktop nav */
nav.dnav {
  display: flex;
  align-items: center;
  gap: 32px;
}
nav.dnav a {
  font-family: var(--font-c);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--white);
  background: none;
  border: none;
  padding: 0;
  transition: opacity 200ms;
  cursor: none;
}
header.hdr-light nav.dnav a { color: var(--black); }
nav.dnav a:hover { opacity: 0.5; }

/* Séparateur + icônes sociales dans le header */
.nav-sep {
  width: 1px;
  height: 16px;
  background: rgba(255,255,255,0.22);
}
header.hdr-light .nav-sep { background: rgba(0,0,0,0.18); }
.nav-social { display: flex; align-items: center; gap: 14px; }
.nav-ic {
  display: inline-flex;
  color: var(--white);
  opacity: 0.82;
  transition: opacity 200ms, transform 200ms ease;
  cursor: none;
}
header.hdr-light .nav-ic { color: var(--black); }
.nav-ic svg { width: 19px; height: 19px; display: block; }
.nav-ic:hover { opacity: 1; transform: translateY(-1px); }

/* Sélecteur de langue FR / EN */
.lang-switch { display: flex; align-items: center; gap: 7px; }
.lang-btn {
  font-family: var(--font-c);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.07em;
  color: var(--white);
  background: none;
  border: none;
  padding: 0;
  cursor: none;
  opacity: 0.45;
  transition: opacity 200ms;
}
header.hdr-light .lang-btn { color: var(--black); }
.lang-btn:hover { opacity: 0.8; }
.lang-btn.active { opacity: 1; text-decoration: underline; text-underline-offset: 4px; }
.lang-div { font-size: 13px; opacity: 0.3; color: currentColor; }
/* Variante dans le menu mobile */
.lang-switch--mob { justify-content: center; gap: 14px; margin-top: 40px; }
.lang-switch--mob .lang-btn { font-size: 16px; letter-spacing: 0.1em; }
.lang-switch--mob .lang-div { font-size: 16px; }

/* Hamburger */
.hbg {
  display: none;
  flex-direction: column;
  gap: 6px;
  background: none;
  border: none;
  padding: 4px;
  cursor: none;
}
.hbg span {
  display: block;
  width: 22px; height: 1px;
  background: var(--white);
}
header.hdr-light .hbg span { background: var(--black); }

/* Header states */
header.hdr-hide { opacity: 0; pointer-events: none; }
header.hdr-show { opacity: 1; pointer-events: auto; transition: opacity 400ms ease-out; }

/* =============================================
   MOBILE MENU
   ============================================= */
.mob-menu {
  position: fixed;
  inset: 0;
  background: var(--black);
  z-index: 9998;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 300ms, visibility 0s 300ms;
}
.mob-menu.open {
  opacity: 1;
  visibility: visible;
  transition: opacity 300ms;
}
.mob-close {
  position: absolute;
  top: 20px; right: 28px;
  background: none;
  border: none;
  color: var(--white);
  font-size: 30px;
  line-height: 1;
  cursor: none;
  font-family: var(--font-j);
}
.mob-menu nav {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
}
.mob-menu nav a {
  font-family: var(--font-c);
  font-weight: 800;
  font-size: clamp(2.6rem, 11vw, 4rem);
  line-height: 1.05;
  color: var(--white);
  text-align: center;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 300ms ease-out, transform 300ms ease-out;
  padding: 8px 0;
  letter-spacing: -0.045em;
}
.mob-menu.open nav a { opacity: 1; transform: translateY(0); }
.mob-menu nav a:hover { opacity: 0.4; }

/* =============================================
   FOOTER
   ============================================= */
footer {
  background: var(--black);
  border-top: 1px solid rgba(255,255,255,0.07);
  padding: 24px 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
footer.ft-light {
  background: var(--white);
  border-top: 1px solid rgba(0,0,0,0.08);
  color: var(--black);
}
.ft-copy, .ft-insta {
  font-family: var(--font-c);
  font-weight: 500;
  font-size: 12.5px;
  letter-spacing: 0.05em;
  opacity: 0.62;
  text-transform: uppercase;
}
.ft-insta { transition: opacity 200ms; }
.ft-insta:hover { opacity: 1; }
.ft-copy {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  opacity: 1;                 /* l'atténuation passe sur les éléments, pour que les liens puissent s'allumer */
}
.ft-copy > span { opacity: 0.62; }
.ft-copy > .ft-sep { opacity: 0.3; }
.ft-link, .legal-inline {
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
}
.ft-link { opacity: 0.62; transition: opacity 200ms; }
.ft-link:hover, .ft-link:focus-visible { opacity: 1; }
.legal-inline { text-decoration: underline; text-underline-offset: 3px; }

/* ---- Mentions légales / Confidentialité : panneau plein écran ---- */
html.legal-open, html.legal-open body { overflow: hidden; }
.legal {
  position: fixed;
  inset: 0;
  z-index: 9500;              /* au-dessus de l'en-tête, sous le curseur */
  background: var(--white);
  color: var(--black);
  opacity: 0;
  transition: opacity 320ms ease;
}
.legal[hidden] { display: none; }
.legal.is-in { opacity: 1; }
.legal-box {
  height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: clamp(80px, 12vh, 120px) 24px clamp(60px, 10vh, 100px);
  outline: none;
}
.legal-doc {
  max-width: 680px;
  margin: 0 auto;
  transform: translateY(16px);
  transition: transform 520ms cubic-bezier(.2,.7,.2,1);
}
.legal.is-in .legal-doc { transform: none; }
.legal-close {
  position: fixed;
  top: clamp(18px, 3vh, 30px);
  right: clamp(18px, 4vw, 40px);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border: 1px solid rgba(0,0,0,0.15);
  border-radius: 999px;
  background: var(--white);
  color: var(--black);
  font-family: var(--font-c);
  font-weight: 600;
  font-size: 12.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: background 200ms, color 200ms;
}
.legal-close span { font-size: 16px; line-height: 1; font-weight: 400; }
.legal-close:hover { background: var(--black); color: var(--white); }
.legal-title {
  font-family: var(--font-c);
  font-weight: 800;
  font-size: clamp(2.4rem, 6.4vw, 4.2rem);
  line-height: 0.98;
  letter-spacing: -0.045em;
  margin-bottom: clamp(28px, 5vh, 48px);
}
.legal-doc h3 {
  font-family: var(--font-c);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 34px 0 10px;
}
.legal-doc p {
  font-family: var(--font-c);
  font-weight: 400;
  font-size: 16.5px;
  line-height: 1.65;
  color: rgba(0,0,0,0.82);
}
.legal-doc p + p { margin-top: 10px; }
.legal-doc a { text-decoration: underline; text-underline-offset: 3px; }
.legal-date { margin-top: 40px; font-size: 14px !important; opacity: 0.6; }
.legal-todo { background: #ffe56a; color: #000; padding: 0 4px; border-radius: 3px; }

/* =============================================
   HOME PAGE — INTRO OVERLAY
   ============================================= */
.intro-wrap {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  height: 100svh;
  background: var(--white);   /* accueil : intro sur fond blanc */
  z-index: 9990;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;       /* cliquable : on entre au clic */
  cursor: none;
}
.intro-logo-el {
  opacity: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 0 5vw;
}

/* Logo "donna lee." en TRÈS GRAND à l'ouverture : le texte est recomposé
   en particules (canvas) qui se dispersent au passage de la souris et se
   reforment ensuite — voir initIntroParticles() dans main.js. */
.intro-logo-name {
  position: relative;
  display: inline-block;
}
.intro-logo-canvas {
  display: block;
  filter: drop-shadow(0 0 18px rgba(255,255,255,0.35));
}
/* Invitation « cliquer / toucher pour entrer » : n'apparaît qu'au bout de
   2 secondes (inutile pour qui entre tout de suite), s'efface dès l'entrée */
.intro-hint {
  position: absolute;
  left: 0; right: 0;
  bottom: clamp(34px, 9vh, 90px);
  text-align: center;
  font-family: var(--font-c);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--white);
  opacity: 0;
  animation: introHint 900ms ease-out 2200ms forwards;
  pointer-events: none;
}
.intro-wrap.is-leaving .intro-hint { animation: none; opacity: 0; transition: opacity 200ms; }
@keyframes introHint { from { opacity: 0; transform: translateY(6px); } to { opacity: 0.62; transform: none; } }
@media (prefers-reduced-motion: reduce) { .intro-hint { opacity: 0.62; } }

/* Téléphone : le logo en vrai texte, net (initIntroStatic) — mêmes
   proportions que la version en particules de l'ordinateur. */
.intro-logo-static {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: var(--font-j);
  font-weight: 800;
  color: var(--white);
  white-space: nowrap;
}
.intro-logo-title {
  font-size: clamp(3.2rem, 15vw, 15rem);
  line-height: 0.95;
  letter-spacing: -0.045em;
  text-transform: lowercase;
}
.intro-logo-sub {
  font-size: clamp(0.8rem, 3.3vw, 2rem);
  line-height: 1.2;
  letter-spacing: 0.01em;
  margin-top: 0.7em;
}
/* Ordinateur peu puissant : même logo net, mêmes proportions que les
   particules, avec leur halo (peint une seule fois, donc gratuit) */
html:not(.is-touch) .intro-logo-static { text-shadow: 0 0 18px rgba(255,255,255,0.35); }
html:not(.is-touch) .intro-logo-sub { font-size: clamp(0.75rem, 2.4vw, 2rem); margin-top: 0.45em; }
/* PC modeste : le halo flou recalculé à chaque image sur le grand canvas
   des particules coûte cher — on l'enlève */
html.hp-lite .intro-logo-canvas { filter: none; }

/* =============================================
   HOME PAGE — HERO VIDÉO + 4 TUILES (plein écran)
   ============================================= */
.hero {
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 540px;
  overflow: hidden;
  background: #000;
  scroll-snap-align: start;
}

/* Vidéo de fond (placeholder — voir assets/hero.mp4) */
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 1;
  opacity: 0;                 /* révélée par JS quand la vidéo a des images */
  transition: opacity 700ms ease;
}
.hero-video.ready { opacity: 1; }

/* Fond animé de secours (avant l'ajout du clip) ; masqué dès que la vidéo
   affiche ses images (classe .has-video posée par initHeroVideo) : sinon son
   dégradé animé était repeint en permanence sous la vidéo pour rien. */
.hero.has-video .hero-fallback { display: none; }
.hero-fallback {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(80% 120% at 18% 12%, rgba(74,74,74,0.55), rgba(0,0,0,0) 55%),
    radial-gradient(70% 90% at 86% 88%, rgba(48,48,48,0.55), rgba(0,0,0,0) 60%),
    linear-gradient(125deg, #181818 0%, #0a0a0a 52%, #1d1d1d 100%);
  background-size: 200% 200%, 200% 200%, 100% 100%;
  animation: heroPan 24s ease-in-out infinite alternate;
}
@keyframes heroPan {
  0%   { background-position: 0% 0%, 100% 100%, 0 0; }
  100% { background-position: 100% 100%, 0% 0%, 0 0; }
}

/* Dégradé global léger : titres lisibles sans survol */
.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(to bottom,
    rgba(0,0,0,0.30) 0%,
    rgba(0,0,0,0) 24%,
    rgba(0,0,0,0) 52%,
    rgba(0,0,0,0.62) 100%);
}

/* Page d'accueil entière cliquable (un appui n'importe où = page suivante, comme
   un défilement). En bas : une fondue noire sur le tiers de la hauteur, qui
   apparaît dès que la souris est sur la vidéo ; sur tactile (pas de survol)
   elle reste là, plus discrète. */
.hero-down {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: block;
  cursor: none;
}
.hero-down::before {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 33%;
  background: linear-gradient(to top,
    rgba(0,0,0,0.78) 0%,
    rgba(0,0,0,0.56) 30%,
    rgba(0,0,0,0.24) 65%,
    rgba(0,0,0,0) 100%);
  opacity: 0;
  transition: opacity 650ms ease;
  pointer-events: none;
}
html.entered .hero:hover .hero-down::before,
.hero-down:focus-visible::before { opacity: 1; }
@media (hover: none) {
  html.entered .hero-down::before { opacity: 0.75; }
}

/* Grain léger sur la vidéo d'accueil : le même motif que celui des vidéos de
   fond des pages suivantes (bulle), en simple transparence (aucun mélange
   d'images). Calque à peine plus grand que l'écran (marge de 72 px, plus que
   le décalage maximal de 70 px : jamais de bord visible) au lieu des 170 %
   d'avant — 2 à 3 fois moins de pixels à composer par-dessus la vidéo.
   Qualité allégée (1) et tactile : pas de grain du tout (comme la bulle) ;
   à l'arrêt quand l'accueil n'est plus à l'écran. */
.hero-grain {
  position: absolute;
  inset: -72px;
  z-index: 2;
  background-image: var(--grain);
  background-size: 140px 140px;
  opacity: 0.32;
  will-change: transform;
  animation: heroGrain 900ms steps(1, end) infinite;
  pointer-events: none;
}
@keyframes heroGrain {
  0%   { transform: translate3d(0, 0, 0); }
  17%  { transform: translate3d(-60px, 40px, 0); }
  34%  { transform: translate3d(55px, -66px, 0); }
  50%  { transform: translate3d(-34px, -50px, 0); }
  67%  { transform: translate3d(46px, 62px, 0); }
  84%  { transform: translate3d(-68px, -22px, 0); }
}
html.hero-off .hero-grain { animation-play-state: paused; }
html.hp-lite .hero-grain { display: none; }
@media (hover: none) { .hero-grain { display: none; } }
@media (prefers-reduced-motion: reduce) { .hero-grain { animation: none; } }

/* Petit repère en bas de la vidéo : un simple trait qui descend en fondu (il
   y a une suite). En pause dès que l'accueil n'est plus à l'écran
   (html.hero-off, initHeroVideo). */
.hero-cue {
  position: absolute;
  left: 50%;
  bottom: clamp(14px, 2.6vh, 26px);
  transform: translateX(-50%);
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  transition: opacity 700ms ease 900ms;
}
html.entered .hero-cue { opacity: 0.85; }
.hero-cue i {
  display: block;
  width: 1px;
  height: 40px;
  background: linear-gradient(to bottom, #fff, rgba(255,255,255,0));
  transform-origin: top;
  animation: heroCue 2200ms cubic-bezier(.6,0,.2,1) infinite;
}
html.hero-off .hero-cue i { animation-play-state: paused; }
@keyframes heroCue {
  0%   { transform: scaleY(0); opacity: 1; }
  55%  { transform: scaleY(1); opacity: 1; }
  100% { transform: scaleY(1); opacity: 0; }
}

/* =============================================
   HOME PAGE — PARTNERS & ARTISTS SECTIONS
   ============================================= */
.hp-section {
  min-height: 100vh;
  min-height: 100svh;
  background: var(--white);   /* accueil inversé : fond blanc */
  color: var(--black);
  padding: calc(var(--h) + 80px) 40px 80px;
  scroll-snap-align: start;
}

.hp-section-title {
  font-family: var(--font-c);
  font-weight: 800;
  font-size: clamp(3.4rem, min(10.3vw, 24vh), 15rem);
  color: var(--black);
  letter-spacing: -0.045em;
  line-height: 0.9;
}

/* Section « à propos » de l'accueil : logo + texte + Instagram + bande de logos */
.hp-section.hp-section--about {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Pas de gap ni de padding ici : .hp-stage doit occuper toute la
     hauteur disponible (jusqu'à la bande du bas), en fond perdu, pour que
     l'effet loupe au curseur reste actif sur toute cette zone — sans bande
     de beige morte en haut ou en bas qui échapperait à l'effet. */
  gap: 0;
  padding: 0;
}
.hp-stage {
  position: relative;
  width: 100%;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.hpabout {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  max-width: min(92vw, 1900px);
  padding: 0 24px;
}
.hpabout-logo {
  font-family: var(--font-j);
  font-weight: 800;
  font-size: clamp(3.6rem, min(10vw, 18vh), 13rem);   /* suit la largeur ET la hauteur de l'écran */
  letter-spacing: -0.045em;
  text-transform: lowercase;
  color: var(--black);
  line-height: 1;
}
.hpabout-tagline {
  display: block;
  font-family: var(--font-j);
  font-weight: 600;
  font-size: clamp(0.95rem, 1.5vw, 1.7rem);
  letter-spacing: 0.02em;
  color: rgba(0,0,0,0.62);
  margin-top: clamp(12px, 1.8vw, 18px);
}
.hpabout-text {
  font-family: var(--font-c);
  font-weight: 400;
  font-size: clamp(1.12rem, min(1.7vw, 3.2vh), 2rem);
  line-height: 1.45;
  color: var(--black);
  max-width: 34em;
  margin-top: clamp(30px, 4.4vw, 50px);
}
/* le nom de l'agence, dans la phrase, reste dans la police du logo */
.hpabout-text strong { font-family: var(--font-j); font-weight: 800; letter-spacing: -0.04em; }

/* Titre + texte des pages « service » qui reprennent le style de la section
   à propos (loupe vidéo au curseur) mais avec une simple accroche, sans logo. */
.pgabout-title {
  font-family: var(--font-c);
  font-weight: 200;                       /* première ligne fine, mot fort en gras (.tx-fort) */
  font-size: clamp(2.3rem, min(6.5vw, 13.5vh), 10.5rem);
  line-height: 0.96;
  letter-spacing: -0.045em;
  color: var(--black);
}
/* Deuxième ligne du titre (« & Influence », « Présence digitale ») : un noir
   légèrement plus clair ; la copie blanche de la bulle reste blanche. */
.pgabout-title .ln + .ln .ln-in { color: #3d3d3d; }
.hp-invert .pgabout-title .ln + .ln .ln-in { color: inherit; }
/* Chaque ligne du titre est une petite fenêtre : à l'arrivée sur la page, le
   texte monte de derrière son bord (voir pageFx, JS). La marge intérieure
   laisse la place aux accents et aux jambages. */
.ln {
  display: block;
  overflow: hidden;
  padding: 0.12em 0.08em 0.16em;
  margin: -0.12em -0.08em -0.16em;
}
.ln-in { display: block; }
.pgabout-sub {
  font-family: var(--font-c);
  font-weight: 400;
  font-size: clamp(1.1rem, 1.55vw, 1.9rem);
  line-height: 1.45;
  color: rgba(0,0,0,0.75);
  max-width: 40ch;
  margin-top: clamp(20px, 2.6vw, 34px);
}
.hp-invert .pgabout-sub { color: var(--white); }

/* ----- Effet loupe inversée qui suit le curseur sur le bloc « à propos » -----
   Un double du bloc (texte clair + vidéo du hero en fond) est superposé au
   bloc normal et révélé dans un cercle net (contour franc, pas de fondu)
   qui suit la souris, via clip-path.
   Seule la vidéo est zoomée (effet loupe) ; le texte, lui, reste à sa place
   exacte au pixel près — sinon la lettre blanche décale par rapport à la
   noire dessous et les deux se chevauchent. */
.hp-invert {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 5;
  opacity: 0;
  transition: opacity 260ms ease;
  background: var(--black);
  /* Forme de la bulle posée en JS (initHpGoo / initHpBlobTouch) : un
     contour organique calculé, appliqué en clip-path. */
  mask-repeat: no-repeat;
  -webkit-mask-repeat: no-repeat;
  mask-size: 100% 100%;
  -webkit-mask-size: 100% 100%;
}
.hp-stage.hp-lens-on .hp-invert { opacity: 1; }
.hp-invert-zoom {
  position: absolute;
  inset: 0;
  transform: scale(1.16);
  transform-origin: var(--mx, 50%) var(--my, 50%);
}
.hp-invert-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.5) saturate(1.35) contrast(1.05);
}
/* Tactile : le filtre (luminosité/contraste) recalculé à chaque image de la vidéo de la bulle pèse lourd sur iPhone ; fond noir derrière → même assombrissement par l'opacité */
@media (hover: none) { .hp-invert-video { filter: none; opacity: 0.5; } }
.hp-invert .hpabout-logo,
.hp-invert .hpabout-tagline,
.hp-invert .hpabout-text,
.hp-invert .pgabout-title,
.hp-invert .pgabout-sub {
  color: var(--white);
  text-shadow: 0 2px 18px rgba(0,0,0,0.65), 0 1px 3px rgba(0,0,0,0.5);
}

.hp-invert-tremble {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: hpTremble 220ms ease-in-out infinite;
}
.hp-invert-grain {
  position: absolute;
  inset: -30%;
  background-image: var(--grain);
  background-size: 140px 140px;
  mix-blend-mode: screen;
  opacity: 0.45;
  animation: hpGrain 900ms steps(6) infinite;
  pointer-events: none;
}
@keyframes hpTremble {
  0%, 100% { transform: translate(0, 0); }
  25%      { transform: translate(0.6px, -0.5px); }
  50%      { transform: translate(-0.6px, 0.5px); }
  75%      { transform: translate(0.5px, 0.6px); }
}
@keyframes hpGrain {
  0%   { transform: translate(0, 0); }
  20%  { transform: translate(-7%, 5%); }
  40%  { transform: translate(6%, -8%); }
  60%  { transform: translate(-4%, -5%); }
  80%  { transform: translate(5%, 6%); }
  100% { transform: translate(0, 0); }
}

/* Tactile : on coupe les effets purement décoratifs de la bulle (grain animé
   en mélange « screen » sur 160 % de la zone, léger tremblement) — très
   coûteux à repeindre sur mobile pour un effet à peine visible. */
@media (hover: none) {
  .hp-invert-grain { display: none; }
  .hp-invert-tremble { animation: none; }
}
/* Bulle hors service (souris ailleurs) : grain et tremblement à l'arrêt.
   PC modeste (html.hp-lite, posé par la qualité adaptative) : supprimés. */
.hp-stage:not(.hp-lens-on) .hp-invert-tremble,
.hp-stage:not(.hp-lens-on) .hp-invert-grain { animation-play-state: paused; }
html.hp-lite .hp-invert-grain { display: none; }
html.hp-lite .hp-invert-tremble { animation: none; }
/* Appareil trop lent (html.fx-off, voir fxInit) : plus de bulle du tout */
html.fx-off .hp-invert { display: none !important; }

/* Tactile : texte non sélectionnable (un doigt posé longtemps pour jouer
   avec la bulle ne déclenche plus la sélection / le menu copier-coller) */
html.is-touch body, html.is-touch body * {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
html.is-touch { -webkit-tap-highlight-color: transparent; }

/* ----- Défilé de mots « machine à sous » (à propos / presse / marketing) -----
   Sous le texte de chaque première page : une fenêtre d'une seule ligne dans
   laquelle les mots se succèdent en boucle infinie — chaque mot chasse le
   précédent en roulant vers le haut, comme un rouleau de machine à sous.
   La pile finit par une copie du premier mot, pour que la boucle se referme
   sans saut visible. L'animation (initWordReels, JS) est pilotée de façon
   synchrone sur le texte noir et sur sa copie blanche de la loupe vidéo
   (.hp-invert) : les deux restent calés sur le même mot. */
.hp-reel {
  --reel-row: clamp(2.8rem, min(5.2vw, 9vh), 6.2rem);
  height: var(--reel-row);
  margin-top: clamp(28px, 4vw, 54px);
  overflow: hidden;
}
.hp-reel-track { margin-top: calc(var(--reel-row) * -1); }
.hp-reel-track {
  list-style: none;
  margin: 0;
  padding: 0;
  will-change: transform;
}
.hp-reel-track li {
  height: var(--reel-row);
  line-height: var(--reel-row);
  font-family: var(--font-c);
  font-weight: 800;
  font-size: clamp(1.8rem, min(3.5vw, 6vh), 4.2rem);
  letter-spacing: -0.03em;
  white-space: nowrap;
  text-align: center;
  color: var(--black);
}
/* Pas d'ombre portée ici : la fenêtre .hp-reel coupe tout ce qui dépasse
   (overflow:hidden), donc un halo se retrouverait découpé en rectangle sombre
   autour du mot dans la bulle. Le fond sombre de la bulle suffit au contraste. */
.hp-invert .hp-reel-track li {
  color: var(--white);
  text-shadow: none;
}

/* ===== Logos partenaires : 2 rangées défilantes en boucle ===== */

.logo-marquee {
  overflow: hidden;
  width: 100%;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.logo-marquee {
  --band-h: clamp(58px, 7.6vw, 112px);   /* taille de la bande de logos */
}
.logo-marquee-track {
  display: inline-flex;
  align-items: center;
  width: max-content;
  animation: marqScroll 92s linear infinite;   /* défilement lent */
  will-change: transform;
}

@keyframes marqScroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.logo-marquee img {
  height: var(--band-h);
  width: auto;
  flex: 0 0 auto;
  /* Espace entre les 2 copies calé sur l'espacement interne réel de la bande
     (mesuré ~0,71×hauteur entre logos), moins la petite marge déjà présente
     aux bords du fichier (~0,23×hauteur) → aucune coupure visible au raccord. */
  margin-right: calc(var(--band-h) * 0.48);
  /* PNG à fond transparent : plus besoin de mélange « multiply » (coûteux à
     recalculer à chaque image d'un défilement continu) */
}

/* Bande de logos du bas (accueil) posée sur un fin socle noir */
.hp-bottomband {
  --band-h: clamp(58px, 7.6vw, 112px);
  width: 100%;
  display: flex;
  flex-direction: column;
}
.hp-socle {
  width: 100%;
  height: calc(var(--band-h) * 0.18);
  background: var(--black);
}

/* ===== Section Artistes : titre puis liste qui défile =====
   Première page : le titre au centre + l'invitation vers Instagram. En
   dessous, tous les artistes en une seule colonne centrée (les plus connus
   d'abord), qui défile avec la page — scroll libre, sans le défilement page
   par page — et reboucle à la fin ; un peu plus bas, la liste s'emballe puis
   le jeu apparaît en fondu (initArtList, JS). */
.hp-section.hp-section--list {
  display: block;
  min-height: 0;
  padding: 0;
  position: relative;
}
.art-intro {
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 540px;
}
/* Pas d'accroche de défilement dans la liste : on la parcourt librement. */
html.art-free { scroll-snap-type: none; }
html.art-locked, html.art-locked body { overflow: hidden !important; }

.art-list {
  list-style: none;
  margin: 0 auto;
  padding: clamp(24px, 6vh, 64px) 0 0;
  width: min(100%, 960px);
  text-align: center;
}
.art-list--loop { padding-top: 0; }
.art-list li {
  padding: clamp(7px, 1.2vh, 14px) 16px;
  font-family: var(--font-c);
  font-weight: 700;
  font-size: clamp(1.3rem, 2.84vw, 3.4rem);
  line-height: 1.1;
  letter-spacing: -0.02em;              /* chaque artiste garde sa propre graphie (daoud, corto.alto…) */
  text-wrap: balance;
  color: var(--black);
  transition: opacity 320ms ease, transform 620ms var(--ease-out);
}
/* Liste vivante (classe posée par initArtList) : le nom au centre de l'écran
   s'allume et grossit d'un rien (6 %), ses voisins à moitié, les autres
   s'adoucissent. Seules quelques classes changent quand on passe d'un nom au
   suivant : aucun calcul par image. */
.art-list.is-focus li { opacity: 0.26; }
.art-list.is-focus li.is-near { opacity: 0.55; transform: scale(1.02); }
.art-list.is-focus li.is-on { opacity: 1; transform: scale(1.06); }
@media (hover: hover) { .art-list.is-focus li:hover { opacity: 1; } }
/* Calque de l'effet « la liste s'emballe puis le jeu apparaît en fondu » (initArtList) */
.art-fx {
  position: fixed;
  inset: 0;
  z-index: 8000;            /* sous l'en-tête (9000) et le curseur */
  overflow: hidden;
  background: var(--white);
  pointer-events: none;
}
.art-fx-col { position: absolute; left: 0; right: 0; top: 0; will-change: transform; }
/* Rideau des contacts : pendant que la roue tourne, la moitié noire de la page
   contacts glisse par-dessus (depuis la gauche ; depuis le haut sur
   téléphone). Dedans, une copie des noms en clair, calée au pixel sur la
   colonne noire : les noms passent du noir au clair en traversant la ligne.
   Le fond du calque devient ainsi exactement celui des contacts. */
.art-fx-half { position: absolute; left: 0; top: 0; overflow: hidden; background: var(--black); will-change: transform; }
.art-center {
  --art-title-size: clamp(3.4rem, min(10.3vw, 24vh), 15rem);
  position: absolute;
  left: 50%;
  top: 50%;
  /* le TITRE (pas le groupe entier) est pile au centre vertical de l'écran */
  transform: translate(-50%, calc(var(--art-title-size) * -0.45));
  z-index: 2;
  width: min(100%, 1900px);
  padding: 0 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(20px, 3.2vh, 34px);
  text-align: center;
}
.art-title { font-size: var(--art-title-size); }
.art-follow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 12px;
  color: rgba(0,0,0,0.72);
  cursor: none;
  transition: color 200ms;
}
.art-follow:hover { color: var(--black); }
.art-follow-txt {
  font-family: var(--font-c);
  font-weight: 600;
  font-size: 13.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.art-follow-arrow {
  width: 56px;
  height: 24px;
  flex: 0 0 auto;
  animation: artArrowNudge 1.6s ease-in-out infinite;
}
.art-follow-ig {
  width: 28px;
  height: 28px;
  flex: 0 0 auto;
  transition: transform 220ms ease;
}
.art-follow:hover .art-follow-ig { transform: scale(1.12) rotate(-4deg); }
/* Téléphone : l'invitation tient sur une seule ligne */
@media (max-width: 480px) {
  .art-follow { gap: 9px; }
  .art-follow-txt { font-size: 12px; letter-spacing: 0.08em; }
  .art-follow-arrow { width: 42px; height: 18px; }
  .art-follow-ig { width: 24px; height: 24px; }
}
@keyframes artArrowNudge {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(5px); }
}
/* ===== Défilement page par page =====
   Une page à la fois (initPagedScroll, JS) : impossible de dépasser des
   sections sans les voir. Le snap CSS reste actif pour le tactile
   (scroll-snap-stop: always empêche de sauter plusieurs pages d'un swipe)
   et se coupe le temps d'une transition animée. Pendant tout défilement,
   la loupe vidéo et le survol des mots se figent (sinon ils tremblent
   sous une souris immobile pendant que la page glisse). */
.hero, .hp-section, #contact { scroll-snap-stop: always; }
footer { scroll-snap-align: end; }
html.is-paging { scroll-snap-type: none; }
html.is-scrolling .hp-stage.hp-lens-on .hp-invert { opacity: 0; }
html.is-scrolling .hp-invert-tremble { animation-play-state: paused; }

/* =============================================
   CONTACT (moitié noire / moitié claire, apparaît en fondu après la roue)
   ============================================= */
#contact {
  background: var(--white);
  color: var(--black);
  min-height: 100vh;
  min-height: 100svh;
  scroll-snap-align: start;
}

/* ----- Contacts : moitié noire / moitié claire ----- */
.con-reveal {
  position: relative;
  display: flex;
  min-height: 100vh;
  min-height: 100svh;
}
.con-reveal-logo {
  position: absolute;
  top: clamp(20px, 4vh, 40px);
  left: clamp(20px, 4vw, 40px);
  z-index: 20;
  cursor: none;
}
.con-reveal-logo .logo-name { transition: opacity 200ms ease; }
.con-reveal-logo:hover .logo-name { opacity: 0.7; }
.con-half {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: calc(var(--h) + 40px) clamp(24px, 6vw, 90px) 60px;
  text-decoration: none;
  cursor: none;
  transition: flex-grow 800ms var(--ease-out);
}
.con-half--dark  { background: var(--black); color: var(--white); align-items: flex-end;   text-align: right; }
.con-half--light { background: var(--white); color: var(--black); align-items: flex-start; text-align: left; }
/* Au survol (ordinateur) : la moitié survolée gagne doucement du terrain,
   l'autre s'efface un peu — plus de moitié grisée. */
.con-half > * { transition: opacity 420ms ease; }
.con-half.is-on  { flex-grow: 1.32; }
.con-half.is-dim > * { opacity: 0.32; }
html.hp-lite .con-half.is-on { flex-grow: 1; }     /* qualité allégée : pas de mise en page animée */
.con-half-name {
  display: block;
  font-family: var(--font-c);
  font-weight: 200;                       /* nom fin… */
  font-size: clamp(2.4rem, min(5.5vw, 12vh), 8rem);
  line-height: 0.96;
  letter-spacing: -0.045em;
}
.con-half-name::first-line { font-weight: 800; }   /* …prénom gras */
.con-half-mail {
  position: relative;
  display: inline-block;
  margin-top: clamp(18px, 2.4vw, 30px);
  font-family: var(--font-c);
  font-weight: 500;
  font-size: clamp(1rem, 1.35vw, 1.7rem);
  border-bottom: 1px solid currentColor;
  padding-bottom: 3px;
}
/* Petite flèche qui glisse à côté de l'adresse au survol */
.con-half-mail::after {
  content: '→';
  position: absolute;
  left: 100%;
  top: 0;
  margin-left: 12px;
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity 300ms ease, transform 500ms var(--ease-out);
}
.con-half--dark .con-half-mail::after { content: '←'; left: auto; right: 100%; margin: 0 12px 0 0; transform: translateX(8px); }
@media (hover: hover) {
  .con-half:hover .con-half-mail::after { opacity: 1; transform: none; }
}
@media (max-width: 768px) {
  .con-reveal { flex-direction: column; }
  .con-half--dark, .con-half--light { align-items: center; text-align: center; }
}

/* =============================================
   RESPONSIVE
   ============================================= */
@media (max-width: 768px) {
  header { padding: 0 20px; }
  nav.dnav { display: none; }
  .hbg { display: flex; }

  /* Hero mobile : la vidéo occupe tout l'écran */
  .hero { height: 100svh; min-height: 100svh; }

  .nav-social { gap: 18px; }

  .hp-section { padding: calc(var(--h) + 50px) 20px 60px; }
  

  

  

  
  

  footer { padding: 20px; flex-direction: column; gap: 10px; text-align: center; }
  .ft-copy { justify-content: center; gap: 4px 8px; line-height: 1.8; }

  .intro-logo-el img { height: 90px; }
}

/* =============================================
   PAGE D'ACCUEIL — INTRO SOMBRE (révèle la vidéo)
   ============================================= */
body.home-inv { background: var(--white); }     /* sections blanches sous le hero */
/* Intro : voile sombre + logo blanc → fondu vers la vidéo du hero */
body.home-inv .intro-wrap { background: #0b0b0b; }
/* L'écran d'entrée sombre est là dès la première image : plus de fondu de
   toute la page (qui laissait voir un écran crème pendant une demi-seconde) */
body.home-inv.page-in, body.home-inv.page-in.page-ready { opacity: 1; transform: none; transition: none; }

/* =============================================
   REPÈRE DE NAVIGATION (bord droit)
   Cinq traits, un par page après la vidéo d'accueil ; celui de la page en
   cours s'allonge. Aucun texte. Absent de l'accueil : il apparaît à partir
   de la page suivante (classe .is-shown, initRail). Cliquable à la souris ;
   sur téléphone, de simples points qui ne captent jamais le doigt.
   ============================================= */
.rail {
  position: fixed;
  right: clamp(12px, 1.8vw, 28px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 8500;                 /* sous l'en-tête, l'écran d'entrée, le menu et le panneau légal */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  color: var(--black);
  opacity: 0;
  visibility: hidden;
  transition: opacity 400ms ease, visibility 0s 400ms;
}
.rail.is-shown { opacity: 1; visibility: visible; transition: opacity 600ms ease 250ms, visibility 0s; }
.rail a {
  display: block;
  padding: 8px 0 8px 18px;
  cursor: none;
}
.rail i {
  display: block;
  width: 30px;
  height: 2px;
  background: currentColor;
  opacity: 0.38;
  transform: scaleX(0.42);
  transform-origin: right center;
  transition: transform 520ms var(--ease-out), opacity 300ms ease;
}
.rail a.is-on i { opacity: 1; transform: scaleX(1); }
@media (hover: hover) {
  .rail a:hover i { opacity: 1; transform: scaleX(0.75); }
  .rail a.is-on:hover i { transform: scaleX(1); }
}
/* Téléphone : cinq points discrets que le doigt traverse */
html.is-touch .rail { right: 9px; pointer-events: none; }
html.is-touch .rail a { padding: 5px 0; }
html.is-touch .rail i { width: 5px; height: 5px; border-radius: 50%; transform: scale(0.7); transform-origin: center; }
html.is-touch .rail a.is-on i { transform: scale(1.25); }
/* Contacts sur téléphone (moitié noire en haut, claire en bas) : points du haut clairs, du bas noirs */
html.is-touch .rail.is-split a:nth-child(-n+2) { color: var(--white); }
html.is-touch .rail.is-split a:nth-child(n+3) { color: var(--black); }
