/* ============================================================
   BLEU SABLE STUDIO — Recherche layout global
   ============================================================ */

:root {
  --bg:           #0F1214;
  --bg-deep:      #0A0C0E;
  --blue:         #5E7B8B;
  --darkblue:     #031E2F;
  --white:        #FFFFFF;
  --white-bright: #FFFFFF;
  --white-soft:   rgba(255, 255, 255, 0.72);
  --white-faint:  rgba(255, 255, 255, 0.45);
  --sand:         #F8D9AB;
  --sand-soft:    rgba(248, 217, 171, 0.78);
  --sand-faint:   rgba(248, 217, 171, 0.55);
  --sand-ghost:   rgba(248, 217, 171, 0.10);
  --rule:         rgba(248, 217, 171, 0.30);

  /* Filets et aplats neutres. Ils DOIVENT être des variables : les sections
     paires inversent l'encre, et toute couleur écrite en dur y resterait
     blanche sur fond clair. */
  --line:         rgba(255, 255, 255, 0.16);
  --line-soft:    rgba(255, 255, 255, 0.12);
  --fill:         rgba(255, 255, 255, 0.04);

  /* Typographie — polices et échelle partagées par les nombreux petits
     intitulés du site (nav, specs, légendes, formulaire, footer…), pour
     n'avoir qu'un endroit à ajuster si la tonalité doit changer. */
  --font-display: 'Barlow', Arial, Helvetica, sans-serif;

  --fw-light:     300;
  --fw-regular:   400;
  --fw-bold:      900;

  --fs-2xs:       11px;
  --fs-xs:        12px;
  --fs-sm:        13px;

  --track-tight:  0.18em;
  --track-narrow: 0.22em;
  --track-mid:    0.28em;
  --track-wide:   0.32em;

  --lh-body:      1.55;

  --ease:         cubic-bezier(.2,.7,.2,1);
  --ease-soft:    cubic-bezier(.4,.0,.2,1);

  /* Échelle d'espacement — un seul jeu de valeurs pour tout le rythme vertical */
  --space-s:      clamp(18px, 2.4vh, 28px);
  --space-m:      clamp(28px, 4vh, 48px);
  --space-l:      clamp(40px, 6vh, 80px);

  /* Encombrement de la capsule audio flottante : sert de réserve à tout
     contenu qui vient en bas d'écran (accueil). */
  /* --capsule-gap:  clamp(18px, 2.4vw, 36px); */
  --capsule-h:    46px;
  --capsule-safe: calc(var(--capsule-gap) + var(--capsule-h) + clamp(14px, 2.2vh, 26px));

  /* La safe-area est absorbée par --pad-x : tout ce qui s'aligne dessus
     (y compris les plein-bords en marge négative) suit automatiquement. */
  --pad-x:        calc(clamp(24px, 6vw, 96px) + max(env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px)));
  --pad-y:        clamp(80px, 12vh, var(--space-l));
  --maxw:         1320px;
  /* Distance réelle du contenu au bord de l'écran : au-delà de 1512px c'est
     la gouttière de .section__inner qui commande, plus --pad-x. */
  --bleed:        max(var(--pad-x), (100vw - var(--maxw)) / 2);
  --nav-h:        76px;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 12px);
}

html, body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--white);
  font-family: 'Sono', 'Manrope', system-ui, -apple-system, sans-serif;
  font-weight: var(--fw-regular);
  font-size: 16px;
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

.hero__line, .service-card__name, .work-plate__artist, .section__subtitle {
  font-family: var(--font-display);
  font-weight: var(--fw-regular);
}

/* clip ne crée pas de scroll container → position: sticky reste fiable
   (hidden est le fallback pour vieux moteurs). */
body { overflow-x: hidden; }
@supports (overflow-x: clip) {
  body { overflow-x: clip; }
}

/* Pendant l'intro : scroll verrouillé */
/* body.is-intro { overflow: hidden; } */

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
img { display: block; max-width: 100%; height: auto; }

::selection { background: var(--sand); color: var(--blue); }

/* ============================================================
   Contenu de page (.site) — masqué pendant l'intro : le loader
   n'a que le grainient en fond. Fade-in à la fin de l'intro.
   ============================================================ */

.site { opacity: 0; }
.site.is-live {
  opacity: 1;
  transition: opacity 1.4s var(--ease-soft) .1s;
}
@media (prefers-reduced-motion: reduce) {
  .site.is-live { transition: none; }
}

/* ============================================================
   Background fixe (grainient) + grain overlay
   ============================================================ */

.grainient {
  position: fixed;
  max-width:100vw;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* filter:brightness(2) blur(25px); */

  /* Même fondu d'entrée que #scene, mais déclenché dès la première image rendue
     (cf. grainient.js) : le fond se matérialise, puis la tempête par-dessus. */
  opacity: 0;
  transition: opacity 2.55s var(--ease-soft);
}
.grainient.is-live { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .grainient { transition: none; }
}

.grain-overlay {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 999999999;  
  mix-blend-mode: color-burn;
  max-width:100vw;
  /* display: none; */
}

/* ============================================================
   Intro (.stage) — présent au load uniquement, puis sortie
   flou + opacité + léger zoom
   ============================================================ */

.stage {
  position: fixed;
  inset: 0;
  z-index: 100;
  overflow: hidden;
  filter: saturate(2);
  -webkit-filter: saturate(2);
  transition:
    opacity   1.15s var(--ease-soft),
    filter    1.15s var(--ease-soft),
    transform 1.15s var(--ease-soft);
}
.stage.is-leaving {
  opacity: 0;
  filter: saturate(2) blur(16px);
  -webkit-filter: saturate(2) blur(16px);
  transform: scale(1.045);
  pointer-events: none;
}
.stage.is-gone { display: none; }

#scene {
  position: absolute;
  inset: 0;
  width: 100%;
  max-width:100vw;
  height: 100%;
  display: block;
  /* Canvas en alpha transparent (cf. renderer dans main.js) :
     les particules s'alpha-composent directement sur le grainient. */

  /* Masqué pendant l'attente de démarrage (LEAD_IN dans main.js) : le rendu de
     warmup y laisse une image figée qu'on ne doit pas voir. Le fond grainient
     occupe l'écran seul, puis la tempête se matérialise en fondu. */
  opacity: 0;
  transition: opacity .55s var(--ease-soft);
}
#scene.is-live { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  #scene { transition: none; }
}

/* ============================================================
   Menu haut
   ============================================================ */

.top-nav {
  position: sticky;
  top: 0; left: 0; right: 0;
  z-index: 80;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 0 var(--pad-x);
  /* Assez opaque pour tenir AUSSI au-dessus de la section claire
     (Prestations) : blanc sur ce fond = 7,2:1 sur clair, 19:1 sur sombre. */
  background: rgba(10, 13, 15, 0.62);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(248, 217, 171, 0.10);
  opacity: 0;
  transform: translateY(-14px);
  pointer-events: none;
  transition: opacity .9s var(--ease), transform .9s var(--ease);
  max-width:100vw;
}
.top-nav.is-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.top-nav__brand {
  padding: 12px 0;
  font-size: var(--fs-sm);
  letter-spacing: var(--track-narrow);
  text-transform: uppercase;
  font-weight: var(--fw-light);
  white-space: nowrap;
  color: var(--white);
  font-family: 'Aileron', no-serif;
}
.top-nav__brand b { font-weight: var(--fw-bold); }

.top-nav__links {
  display: flex;
  align-items: center;
  gap: clamp(18px, 3.4vw, 48px);
}
.top-nav__link {
  position: relative;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--white-soft);
  padding: 14px 0;            /* cible tactile 46px */
  transition: color .4s var(--ease);
}
.top-nav__link::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 10px;
  height: 1px;
  background: var(--sand);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .5s var(--ease);
}
.top-nav__link:hover { color: var(--white); }
.top-nav__link.is-active { color: var(--white); }
.top-nav__link:hover::after,
.top-nav__link.is-active::after { transform: scaleX(1); }

/* ============================================================
   Capsule audio (bouton flottant, bas-gauche)
   ============================================================ */

.capsule {
  position: fixed;
  /* alignée sur --pad-x : même bord gauche que le wordmark du menu et que
     le contenu de toutes les sections */
  left: var(--pad-x);
  bottom: calc(var(--capsule-gap) + env(safe-area-inset-bottom, 0px));
  z-index: 70;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 12px 18px 12px 14px;
  border-radius: 0px;
  background: rgba(15, 18, 20, 0.62);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--rule);
  color: var(--white);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .8s var(--ease), transform .8s var(--ease), border-color .35s var(--ease), background .35s var(--ease);
}
.capsule.is-visible { opacity: 1; transform: translateY(0); }
.capsule:hover { border-color: var(--white-soft); background: rgba(15, 18, 20, 0.8); }

.capsule__ring {
  position: relative;
  width: 22px;
  height: 22px;
  /* border-radius: 0;
  border: 1px solid var(--white-soft); */
  display: grid;
  place-items: center;
  flex: 0 0 auto;
}
.capsule__ring::before {
  content: "";
  width: 0; height: 0;
  border-left: 10px solid var(--white);
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  margin-left: 2px;
  transition: opacity .25s var(--ease);
}
.capsule.is-playing .capsule__ring::before { opacity: 0; }

.capsule__bars {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(4, 2px);
  gap: 2px;
  place-content: center;
  align-items: end;
  opacity: 0;
  transition: opacity .25s var(--ease);
}
.capsule__bars i {
  display: block;
  width: 2px;
  background: var(--white);
  height: 4px;
  /* border-radius: 1px; */
  animation: bar 1s ease-in-out infinite;
}
.capsule__bars i:nth-child(2) { animation-delay: .15s; }
.capsule__bars i:nth-child(3) { animation-delay: .30s; }
.capsule__bars i:nth-child(4) { animation-delay: .45s; }
.capsule.is-playing .capsule__bars { opacity: 1; }
@keyframes bar {
  0%, 100% { height: 4px; }
  50%      { height: 14px; }
}
@media (prefers-reduced-motion: reduce) {
  .capsule__bars i { animation: none; height: 9px; }
}

.capsule__label { line-height: 1; }

/* ============================================================
   Sections (cadre commun)
   ============================================================
   Plus aucun mix-blend-mode dans le projet : .section peut porter
   un z-index sans rien casser (contrainte levée). */

.section {
  position: relative;
  padding: var(--pad-y) var(--pad-x);
}

/* Wrapper responsive commun au contenu de chaque section */
.section__inner {
  position: relative;
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
}

.section__head {
  /* display: grid;
  grid-template-columns: auto auto 1fr; */
  align-items: baseline;
  gap: 22px;
  margin-bottom: var(--space-m);
  text-align: center;
  color: var(--white);
}
.section__num {
  font-weight: var(--fw-bold);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-wide);
  color: var(--white-soft);
}
.section__title {
  margin: 0;
  font-weight: var(--fw-bold);
  font-size: clamp(40px, 6.4vw, 92px);
  line-height: 0.95;
  color: var(--white);
  font-family: var(--font-display);
  /* text-transform: uppercase; */
}
.section__title .t-light {
  font-weight: var(--fw-light);
  color: var(--white-soft);
  margin-right: 0.18em;
}
.section__rule {
  display: block;
  height: 1px;
  background: var(--rule);
  align-self: center;
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 1.4s var(--ease) .15s;
}
.section.is-in-view .section__rule { transform: scaleX(1); }

/* ============================================================
   Fonds de sections
   - Studio        : transparent (grainient nu)
   - Prestations   : voile papier sable 92 % — SEULE section claire du site
   - Réalisations  : voile sombre translucide (le grainient repasse dessous)
   - Contact       : voile bleu profond + filet sable
   ============================================================ */

.section__bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* Voile papier. La rampe d'alpha sur les bords (0.86 → 0.92) ne sert pas à
   fondre la démarcation — l'arête reste franche — mais à éviter l'aplat mort :
   le grainient module encore le panneau de ~2,4 L*. Stops en px et non en %
   pour que la rampe ne « respire » pas quand un panneau de service s'ouvre. */
.section:nth-child(2n+1) .section__bg {
  --fade: clamp(48px, 7vh, 96px);
  background: linear-gradient(
    180deg,
    rgba(249, 244, 234, 0.86) 0,
    rgba(249, 244, 234, 0.92) var(--fade),
    rgba(249, 244, 234, 0.92) calc(100% - var(--fade)),
    rgba(249, 244, 234, 0.86) 100%
  );
}

/* Le fond devient clair → toute la rubrique passe en encre sombre via les
   custom properties. Le sable pur donnerait 1,14:1 sur ce panneau : il est
   remappé sur une encre bleutée le temps de la section. */
.section:nth-child(2n+1) {
  --white:        #0A1B26;
  --white-bright: #03141F;
  --white-soft:   rgba(6, 25, 37, 0.82);
  --white-faint:  rgba(6, 25, 37, 0.66);
  --rule:         rgba(6, 25, 37, 0.30);
  --sand:         #1F3A47;
  --sand-soft:    rgba(31, 58, 71, 0.82);
  --sand-faint:   rgba(31, 58, 71, 0.60);
  --sand-ghost:   rgba(6, 25, 37, 0.06);
  --line:         rgba(6, 25, 37, 0.22);
  --line-soft:    rgba(6, 25, 37, 0.16);
  --fill:         rgba(6, 25, 37, 0.05);
}
.section:nth-child(2n) ::selection { background: #1F3A47; color: #E7E1D6; }


.section--contact {
  border-top: 1px solid var(--rule);
  padding-bottom: calc(var(--pad-y) + env(safe-area-inset-bottom, 0px));
}

/* ============================================================
   Reveal au scroll — fade + translate Y léger.
   Observé seulement après l'intro (cf. sections.js), stagger via --d.
   ============================================================ */

.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 1s var(--ease), transform 1.1s var(--ease);
}
.reveal.is-in {
  opacity: 1;
  transform: translateY(0);
  transition-delay: var(--d, 0ms);
}
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* ============================================================
   Accueil — une photo, une ligne. Le menu flotte par-dessus la photo.
   ============================================================ */

/* Colonne pleine hauteur : la photo absorbe TOUT l'espace restant (flex: 1),
   le texte garde une hauteur fixe et la réserve du bas tient la capsule à
   distance. Aucun vide résiduel, quelle que soit la hauteur d'écran. */
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100svh;          /* évite le saut quand la barre d'URL mobile se replie */
  min-height: 480px;
  /* padding: 0 var(--pad-x) var(--capsule-safe); */
}
.hero__media {
  position: relative;
  flex: 1 1 0;
  min-width:100%;
  max-width:100vw;
  min-height: 0;
  margin:0;
  overflow: hidden;
  isolation: isolate;
  clip-path: inset(0);
  background: #0c0c0c center / cover no-repeat;
  background-image: url('./vids/hero_poster.jpg');
}
.hero__media img,
.hero__media video  {
  width: 100%;
  max-width: 100vw;
  height: 100%;
  object-fit: cover;
  object-position: center;
  position: absolute;
  inset: 0;
  /* iOS : `position:fixed` + clip-path pose la vidéo sur un calque
     séparé qui n'est ni clippé ni lu correctement. */
  /* les photos d'origine sont très saturées (éclairage scène) : léger
     dégrisement pour qu'elles tiennent dans la palette. À ajuster. */
  filter: saturate(.88) contrast(1.02);
}
.hero__text {
  flex: 0 0 auto;
  margin-top: var(--space-m);
}
.hero__line {
  margin: 0;
  font-weight: var(--fw-light);
  font-size: clamp(21px, 2.4vw, 34px);
  line-height: 1.3;
  letter-spacing: -0.005em;
  color: var(--white);
  max-width: 26ch;
}
.hero__place {
  margin: 14px 0 0;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--white-faint);
}

/* ============================================================
   Section — STUDIO
   Texte en tête, specs en bandeau, deux photos légendées.
   Pas de sticky : on lit, on descend.
   ============================================================ */

.studio__copy {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(24px, 4vw, 72px);
  align-items: start;
}
.studio__copy p { margin: 0; }

.studio__plates {
  margin-top: var(--space-l);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(20px, 2.6vw, 40px);
  align-items: start;
}

.plate { margin: 0; }

.plate img {
  display: block;
  width: 100%;
  /* les deux photos n'ont pas le même format natif : on les ramène au même
     rapport pour que la paire retombe d'aplomb */
  aspect-ratio: 4 / 4;
  object-fit: cover;
  /* border-radius: 2px; */
  background: var(--bg-deep);
  opacity: 1;
  /* Léger dégrisement : les photos d'origine sont très saturées (éclairage
     scène) et jureraient avec la palette bleu-gris. À ajuster si besoin. */
  filter: saturate(.88) contrast(1.02);
  transition: opacity 1.2s var(--ease);
}

.plate figcaption {
  position: relative;
  margin-top: 16px;
  display: flex;
  align-items: baseline;
  gap: 16px;
}

.plate__n {
  flex: none;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  color: var(--sand-faint);
}
.plate__t {
  font-size: var(--fs-sm);
  line-height: 1.45;
  color: var(--white-faint);
}

@media (prefers-reduced-motion: reduce) {
  .plate figcaption::before { transform: scaleX(1); transition: none; }
  .plate img { transition: none; }
}

.lede {
  font-size: clamp(17px, 1.2vw, 20px);
  line-height: var(--lh-body);
  color: var(--white);
  margin: 0 0 18px;
}
.lede em { font-style: italic; color: var(--white-bright); }

.studio__copy p { color: var(--white-soft); }
.studio__copy .lede { color: var(--white); margin-bottom: 0; }

.studio__specs {
  list-style: none;
  margin: var(--space-m) 0 0;
  padding: 22px 0 0;
  border-top: 1px solid var(--rule);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px 22px;
}
.studio__specs li {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--fs-sm);
}
.studio__specs span {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--white-faint);
}
.studio__specs b {
  font-weight: var(--fw-light);
  color: var(--white);
}

/* ============================================================
   Section — PRESTATIONS (cases côte à côte + panneau de texte)
   ≥1024px : 3 cases en ligne, le texte de la case active s'affiche
   SOUS la rangée (panneaux superposés dans la même cellule de grille).
   <1024px : cases empilées, le texte se déplie sous LA case cliquée.
   ============================================================ */

.services {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(14px, 1.8vw, 26px);
}

.service-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: clamp(20px, 2.6vw, 32px);
  padding-right: clamp(44px, 5vw, 56px);   /* place pour la coche */
  border: 3px solid var(--rule);
  /* border-radius: 3px; */
  text-align: left;
  cursor: pointer;
  /* le panneau se déplie sous la case : elle ne doit pas passer sous le menu */
  scroll-margin-top: calc(var(--nav-h) + 16px);
  transition: border-color .45s var(--ease), background .45s var(--ease), transform .45s var(--ease);
}
.service-card:hover {
  border-color: var(--white-faint);
  transform: translateY(-3px);
}
.service.is-open .service-card {
  border-color: var(--white);
  background: var(--sand-ghost);
  color: var(--darkblue);
  transform: none;
}

.service-card__idx {
  font-style: italic;
  font-weight: var(--fw-light);
  font-size: var(--fs-sm);
  color: var(--white-faint);
  letter-spacing: 0.04em;
}
.service-card__name {
  font-size: clamp(22px, 2.4vw, 34px);
  line-height: 1;
  color: var(--white);
}
.service-card__tag {
  font-weight: var(--fw-light);
  /* font-style: italic; */
  font-size: var(--fs-sm);
  color: var(--white-soft);
  display: none;
}

/* « Case cochée » : petit rond qui se remplit */
.service-card__check {
  position: absolute;
  top: clamp(20px, 2.6vw, 32px);
  right: clamp(16px, 2vw, 24px);
  width: 16px;
  height: 16px;
  border: 1px solid var(--white-faint);
  /* border-radius: 50%; */
  transition: border-color .4s var(--ease);
}
.service-card__check::after {
  content: "";
  position: absolute;
  inset: 3px;
  /* border-radius: 50%; */
  background: var(--white);
  transform: scale(0);
  transition: transform .4s var(--ease);
}
.service.is-open .service-card__check { border-color: var(--white); }
.service.is-open .service-card__check::after { transform: scale(1); }

.service__content { padding-top: var(--space-s); }

.service__cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(20px, 3vw, 48px);
}

.service__intro,
.service__vision { margin: 0; }
.service__intro {
  font-size: clamp(15px, 1.05vw, 18px);
  color: var(--white);
}
.service__intro em { color: var(--white-bright); font-style: italic; }

.service__vision {
  color: var(--white-soft);
  font-size: 14.5px;
}
.service__vision em { color: var(--white); font-style: italic; }

.service__tags {
  list-style: none;
  margin: 26px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
}
.service__tags li {
  flex: 0 0 auto;
  font-size: var(--fs-xs);
  line-height: 1;
  letter-spacing: var(--track-narrow);
  text-transform: uppercase;
  padding: 8px 14px;
  border: 1px solid var(--rule);
  /* border-radius: 999px; */
  color: var(--white-soft);
}

/* Panneau dépliant — même mécanique aux deux tailles : la hauteur est animée
   par grid-template-rows 0fr → 1fr (le conteneur s'agrandit), puis le texte
   monte en opacité une fois la place faite. */
.service-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .6s var(--ease);
}
.service-panel__in {
  overflow: hidden;
  min-height: 0;
  /* replié = hors du parcours de tabulation, mais seulement une fois
     l'animation de fermeture terminée */
  visibility: hidden;
  transition: visibility 0s .6s;
}
.service.is-open .service-panel { grid-template-rows: 1fr; }
.service.is-open .service-panel__in { visibility: visible; transition: visibility 0s; }

.service__content {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.service.is-open .service__content {
  opacity: 1;
  transform: none;
  transition-delay: .18s;      /* le texte suit l'ouverture, il ne la précède pas */
}
@media (prefers-reduced-motion: reduce) {
  .service-panel { transition: none; }
  .service__content { transition: none; transform: none; }
}

/* ----- ≥1024px : cases en rangée 1, panneaux superposés en rangée 2 -----
   Superposés dans la même cellule : la rangée prend la hauteur du seul
   panneau ouvert (les autres sont à 0fr), donc aucun vide quand tout est
   fermé et aucun saut quand on passe d'une case à l'autre. */
@media (min-width: 1024px) {
  .services { row-gap: 0; }
  .service { display: contents; }

  .service-card  { grid-row: 1; }
  .service__content { padding-top: var(--space-m); }  
  .service-panel {
    grid-row: 2;
    grid-column: 1 / -1;
    align-self: start;
  }
}

/* ----- <1024px : cases empilées, panneau sous la case cliquée ----- */
@media (max-width: 1023px) {
  .services { grid-template-columns: 1fr; gap: 12px; }

  .service-card { width: 100%; }

  .service__content { padding-bottom: 14px; }
  .service__cols { grid-template-columns: 1fr; }
}

/* ============================================================
   Section — RÉALISATIONS
   Plaques typographiques sur rail : pas de boîte, pas d'ombre,
   pas de fond. Le vide fait la séparation, l'opacité fait le focus.
   ============================================================ */

.works-carousel { position: relative; }

.works-carousel__viewport {
  overflow: hidden;
  cursor: grab;
  touch-action: pan-y;         /* le scroll vertical de la page reste natif */
  margin-inline: calc(-1 * var(--bleed));
  margin-bottom:48px;
  /* margin: 0 auto;
  box-sizing: border-box;
  max-width: min(100vw,3840px); */
  /* les plaques amorcées se dissolvent aux deux bords au lieu d'être
     tranchées : le rail est centré, donc le fondu est symétrique */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
}
.works-carousel__viewport.is-dragging {
  cursor: grabbing;
  user-select: none;
}
/* le masque clipperait l'outline : on le porte sur le parent */
.works-carousel__viewport:focus-visible { outline: none; }
.works-carousel:has(.works-carousel__viewport:focus-visible) {
  outline: 1px dashed var(--rule);
  outline-offset: 10px;
}

.works-track {
  --slot: clamp(200px, 25vw, 620px);
  list-style: none;
  margin: 0;
  padding: var(--space-m) var(--bleed) 6px;
  display: flex;
  gap: clamp(40px, 5.2vw, 88px);
  width: max-content;
  will-change: transform;
}

.work-plate {
  flex: 0 0 var(--slot);
  /* assez haut pour que les lignes de base des 5 plaques s'alignent,
     pas au point de creuser un trou entre la méta et le titre */
  /* min-height: clamp(200px, 30vh, 340px); */
  display: flex;
  flex-direction: column;
  /* gap: clamp(20px, 2.4vh, 32px); */
  /* padding-top: clamp(16px, 2vh, 26px); */
  /* border-top: 1px solid var(--line); */
  /* padding-right:clamp(40px, 5.2vw, 88px); */
  transform:scale(0.8);
  transition: opacity .8s var(--ease-soft), border-right-color .9s var(--ease-soft), transform 0.8s var(--ease-soft);
  padding: 24px 24px 32px;
  background:var(--white);
}

/* .work-plate:not(:last-child) {
  border-right: 1px solid var(--line);
} */

/* le mode focus n'existe que si le JS tourne : sans lui, tout reste lisible */
.works-track.is-focusmode .work-plate { opacity: .26; cursor: pointer; }
.works-track.is-focusmode .work-plate.is-active {
  opacity: 1;
  border-right-color: var(--sand-faint);
  transform:scale(1);
}
@media (prefers-contrast: more) {
  .works-track.is-focusmode .work-plate { opacity: .62; }
}

.work-plate__header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.work-plate__meta {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: clamp(10px, .78vw, 12px);
  letter-spacing: .26em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--black);
}
.work-plate__idx { color: var(--white); }
.work-plate__sep { opacity: .45; }
.work-plate__role {
  margin: 0;
  text-align: center;
  font-size: clamp(10px, .78vw, 12px);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--black);
}

/* les lignes de base des 5 plaques s'alignent → l'ensemble lit « composé » */
.work-plate__body {
  align-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(16px, 1.6vw, 24px);
}


/* Emplacement de pochette. Vide, c'est un cadre en attente ; dès qu'une
   image y est glissée elle le remplit sans autre réglage. */
.work-plate__cover {
  flex: 0 0 auto;
  width: calc(100% - 96px);
  aspect-ratio: 1;
  border: 1px solid var(--line);
  background: var(--fill);
  overflow: hidden;
}
.work-plate__cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border:2px solid white;
}

.work-plate__titles { 
  min-width: 0;
  text-align: center; 
}

.work-plate__artist {
  margin: 0;
  font-size: clamp(28px, 3.6vw, 54px);
  line-height: .96;
  letter-spacing: -.02em;
  color: var(--black);
  text-wrap: balance;
}
.work-plate__album {
  margin: 12px 0 0;
  font-weight: var(--fw-light);
  /* font-style: italic; */
  font-size: clamp(17px, 1.6vw, 25px);
  line-height: 1.15;
  color: var(--black);   /* l'unique accent sable de la plaque */
}
.work-plate__format {
  margin: 8px 0 0;
  font-size: var(--fs-2xs);
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--black);
}

.work-plate a {
  pointer-events: all;
}

/* Barre de progression + compteur + flèches */
.works-carousel__footer {
  display: flex;
  align-items: center;
  gap: clamp(20px, 3vw, 36px);
  /* margin-top: var(--space-m); */
}
.works-carousel__progress {
  flex: 1;
  height: 1px;
  background: var(--line-soft);
  display:none;
}
.works-carousel__progress span {
  display: block;
  height: 100%;
  background: var(--sand);
  transform: scaleX(0);
  transform-origin: left center;
}
.works-carousel__nav {
  display: flex;
  margin: 0 auto;
  align-items: center;
  gap: 16px;
}
.works-carousel__count {
  margin: 0;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  color: var(--white-faint);
  font-variant-numeric: tabular-nums;
  display:none;
}
.works-carousel__count b { color: var(--white-soft); }
.works-carousel__btn {
  font-family: 'Sono';
  width: 64px;
  height:64px;
  /* border: 1px solid var(--rule); */
  background: black;
  color:#E7E1D6;
  /* border-radius: 50%; */
  /* color: var(--white-soft); */
  font-size: 64px;
  line-height: 1;
  display: grid;
  place-items: center;
  transition: border-color .35s var(--ease), color .35s var(--ease), opacity .35s var(--ease);

  display:none;
}
.works-carousel__btn:hover {
  border-color: var(--sand);
  color: var(--black);
}
.works-carousel__btn:disabled {
  opacity: 0.25;
  pointer-events: none;
}

/* ============================================================
   Section — CONTACT
   ============================================================ */

.contact {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: clamp(32px, 6vw, 96px);
  align-items: start;
}

.contact__aside .lede { margin-bottom: 36px; }

.contact__meta {
  list-style: none;
  margin: 0;
  padding: 0 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.contact__meta li {
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: 18px;
  font-size: 14px;
  color: var(--white);
}
.contact__meta span {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--white-faint);
  padding-top: 2px;
}
.contact__meta a {
  display: inline-block;
  padding: 10px 0;
  margin: -10px 0;
  border-bottom: 1px solid transparent;
  transition: border-color .35s var(--ease);
}
/* .contact__meta a:hover { border-color: var(--white-soft); } */

/* ----- Form ----- */
.form {
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.field {
  position: relative;
  display: flex;
  flex-direction: column;
}
.field label {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--white-faint);
  margin-bottom: 8px;
  transition: color .35s var(--ease);
}
.field input,
.field select,
.field textarea {
  width: 100%;
  background: transparent;
  border: 0;
  border: 1px solid var(--white-soft);
  color: var(--white);
  font: inherit;
  font-size: 16px;
  padding: 8px 8px;
  outline: none;
  /* border-radius: 0; */
  appearance: none;
  -webkit-appearance: none;
  resize: vertical;
}
.field select {
  background-image:
    linear-gradient(45deg, transparent 50%, var(--white-soft) 50%),
    linear-gradient(135deg, var(--white-soft) 50%, transparent 50%);
  background-position: calc(100% - 16px) center, calc(100% - 10px) center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 28px;
}
.field select option { background: var(--bg); color: #FFFFFF; }

.field__line {
  position: absolute;
  left: 0; right: 0;
  bottom: 0;
  height: 1px;
  background: var(--white);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .55s var(--ease);
  pointer-events: none;
}
/* .field input:focus ~ .field__line,
.field select:focus ~ .field__line,
.field textarea:focus ~ .field__line { transform: scaleX(1); } */

.field:focus-within label { color: var(--white); }

/* File drop */
.field--file { margin-top: 6px; }
.file-drop {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 20px;
  border: 1px dashed var(--white-soft);
  /* border-radius: 2px; */
  cursor: pointer;
  transition: border-color .4s var(--ease), background .4s var(--ease);
  margin-bottom: 0;
}
.file-drop:hover,
.file-drop.is-drag {
  border-color: var(--white-soft);
  background: rgba(248, 217, 171, 0.03);
}
.file-drop.is-loaded { border-color: var(--white-soft); border-style: solid; }
.file-drop__icon {
  position: relative;
  color: var(--white-soft);
  width: 36px; height: 36px;
  flex: 0 0 36px;
  border: 1px solid var(--rule);
  /* border-radius: 50%; */
  transition: transform .45s var(--ease), border-color .35s var(--ease), color .35s var(--ease);
}
/* Croix construite en CSS : deux barres centrées au pixel près,
   indépendantes des métriques de la police. */
.file-drop__icon::before,
.file-drop__icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: currentColor;
  transition: background .35s var(--ease);
}
.file-drop__icon::before {
  /* barre horizontale */
  width: 12px;
  height: 1px;
  transform: translate(-50%, -50%);
}
.file-drop__icon::after {
  /* barre verticale */
  width: 1px;
  height: 12px;
  transform: translate(-50%, -50%);
}
.file-drop:hover .file-drop__icon { transform: rotate(90deg); border-color: var(--white-soft); color: var(--white); }
.file-drop.is-loaded .file-drop__icon { transform: rotate(45deg); color: var(--white); border-color: var(--white); }
.file-drop__text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--fs-sm);
  color: var(--white);
  min-width: 0;
}
.file-drop__text b { font-weight: var(--fw-regular); color: var(--white); overflow-wrap: anywhere; }
.file-drop__text small {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--white-faint);
}

.btn-send {
  margin-top: 18px;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 14px 22px 14px 24px;
  border: 1px solid var(--white-soft);
  /* border-radius: 999px; */
  color: var(--white);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  transition: background .4s var(--ease), color .4s var(--ease), border-color .4s var(--ease), transform .35s var(--ease);
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.btn-send:hover {
  background: var(--white);
  color: var(--bg);
  border-color: var(--white);
}
.btn-send:disabled { opacity: .5; pointer-events: none; }
.btn-send__arrow {
  display: inline-block;
  transition: transform .35s var(--ease);
}
.btn-send:hover .btn-send__arrow { transform: translateX(6px); }

.form__feedback {
  margin: 8px 0 0;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-tight);
  text-transform: uppercase;
  color: var(--white-soft);
  min-height: 16px;
}
.form__feedback.is-ok    { color: var(--white); }
.form__feedback.is-error { color: #E8867D; }

/* ============================================================
   Footer
   ============================================================ */

.footer {
  margin-top: var(--space-l);
  padding: 28px 0 0;
  border-top: 1px solid var(--white-soft);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--white-soft);
}
.footer a:hover { color: var(--white); }

/* ============================================================
   Responsive
   ============================================================ */

/* ----- Menu : plus de place pour marque + 4 liens dès 860px ----- */
@media (max-width: 860px) {
  .top-nav { padding: 0 20px; gap: 0; }
  .top-nav__brand { display: none; }
  .top-nav__links {
    width: 100%;
    justify-content: space-between;
    gap: 10px;
  }
  .top-nav__link { font-size: var(--fs-xs); letter-spacing: .10em; }
}

/* ----- Réalisations : plaques resserrées ----- */
@media (max-width: 1023px) {
  .works-track { --slot: 31vw; gap: 40px; }
  .work-plate { min-height: clamp(190px, 28vh, 300px); }
  .work-plate__artist { font-size: clamp(28px, 4.6vw, 40px); }
  .work-plate__album  { font-size: clamp(17px, 2.4vw, 21px); }
}

@media (max-width: 900px) {
  .section__head { grid-template-columns: auto 1fr; }
  .section__rule { display: none; }

  .studio__copy { grid-template-columns: 1fr; gap: 18px; }
  .studio__specs { grid-template-columns: 1fr 1fr; }

  .contact { grid-template-columns: 1fr; }
}

/* ----- Studio : une photo par ligne, en plein bord ----- */
@media (max-width: 700px) {
  .studio__plates { grid-template-columns: 1fr; gap: 32px; }
  /* .plate { margin-inline: calc(-1 * var(--pad-x)); } */
  .plate img { border-radius: 0; aspect-ratio: 3 / 2; }
  /* margin (et non padding) : le filet ::before doit rester aligné au texte */
  /* .plate figcaption { margin-inline: var(--pad-x); } */

  /* .hero__media img { height: min(54vh, 420px); } */
}

/* ----- Footer empilé ----- */
@media (max-width: 620px) {
  .footer {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    letter-spacing: var(--track-tight);
  }
  .footer a { padding: 10px 0; }
}

@media (max-width: 560px) {
  /* --pad-x unifié : .works-track (padding) et les plein-bords (marge
     négative) doivent tomber exactement sur le padding de .section. */
  :root {
    --pad-x: calc(22px + max(env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px)));
  }

  .capsule__label { display: none; }
  .capsule { padding: 11px; }

  .section__head { gap: 12px; }
  .section__title { font-size: clamp(48px, 6.4vw, 92px); }

  .works-track { --slot: 62vw; gap: 16px; }
  .work-plate { min-height: 200px; padding-top: 14px; }
  /* le tracking doit descendre avec la taille, sinon la méta passe
     sur 2 lignes sous 360px */
  .work-plate__meta { font-size: 10px; letter-spacing: .20em; gap: 8px; }
  .work-plate__role { letter-spacing: .14em; }
  .work-plate__artist { font-size: clamp(26px, 7.2vw, 36px); }
  .work-plate__album  { font-size: clamp(16px, 4vw, 20px); }
  .work-plate__cover  { width: 192px; }
  .work-plate__body   { gap: 14px; }

  .works-carousel__viewport {
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 88%, transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 88%, transparent 100%);
  }
}

/* ----- Menu sur deux rangées quand 4 liens ne tiennent plus ----- */
@media (max-width: 430px) {
  :root { --nav-h: 92px; }
  .top-nav__links {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 2px;
    column-gap: 18px;
  }
  .top-nav__link { letter-spacing: .14em; padding: 12px 0; }
}

/* ----- Specs studio sur une colonne ----- */
@media (max-width: 420px) {
  .studio__specs { grid-template-columns: 1fr; gap: 12px; }
  .studio__specs li {
    flex-direction: row;
    justify-content: space-between;
    align-items: baseline;
    gap: 16px;
  }
  .studio__specs span { flex: 0 0 auto; }
  .studio__specs b { text-align: right; }
}

/* ----- Paysage court : le rythme vertical se resserre ----- */
@media (orientation: landscape) and (max-height: 540px) {
  :root { --pad-y: 44px; --nav-h: 56px; }
  .section__head { margin-bottom: 24px; }
  .section__title { font-size: clamp(30px, 7vh, 92px); }
  .work-plate { min-height: 200px; gap: 16px; }
  .work-plate__artist { font-size: clamp(26px, 3.6vw, 40px); }
}

/* ============================================================
   Reduced motion : le rail redevient un scroller natif
   ============================================================ */

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

  .works-carousel__viewport {
    overflow-x: auto;
    touch-action: auto;            /* sinon inutilisable au doigt */
    scroll-snap-type: x proximity;
    scrollbar-width: none;
  }
  .works-carousel__viewport::-webkit-scrollbar { display: none; }
  .works-track {
    transform: none !important;
    /* le JS ne mesure pas dans ce mode : le rembourrage qui permet aux
       plaques d'extrémité de se centrer est donc calculé en CSS */
    padding-inline: max(var(--bleed), (100vw - var(--slot)) / 2);
  }
  .work-plate { scroll-snap-align: center; }
}
