/* ═══════════════════════════════════════════════════════════
   STILL FLOW — couche d'animation
   Moteur repris du skill « Site Immersif » : smooth scroll lerp,
   scènes épinglées scrubées, tracés dessinés, rideau de lettres.
   Aucune règle ici ne change le contenu ni la mise en page de la
   maquette : seulement des états d'entrée et des transitions.
   ═══════════════════════════════════════════════════════════ */

:root {
  --ease-out: cubic-bezier(0.19, 1, 0.22, 1);
  --ease-inout: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-soft: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ═══════════ SMOOTH WRAPPER ═══════════ */
html.is-smooth { scroll-behavior: auto; }
body.is-smooth .smooth {
  position: fixed;
  top: 0; left: 0;
  width: 100%;
  will-change: transform;
}

/* ═══════════ SCÈNES (pin émulé) ═══════════ */
.scene { position: relative; height: calc(var(--pin, 1) * 100vh); }
.s-hero { --pin: 4.6; }
.s-process { --pin: 4.2; }
.scene .pin {
  position: relative;
  height: 100vh;
  /* sur téléphone, 100vh dépasse l'écran visible tant que la barre du
     navigateur est affichée : dvh suit la hauteur réellement visible, les
     visuels ancrés en bas du hero restent donc entiers */
  height: 100dvh;
  overflow: hidden;
  will-change: transform;
}
/* sans moteur (mouvement réduit) : on retombe sur le sticky natif */
body:not(.is-smooth) .scene .pin { position: sticky; top: 0; }

/* ═══════════ LOADER ═══════════ */
.loader {
  position: fixed; inset: 0;
  z-index: 100;
  display: flex; align-items: center; justify-content: center;
}
.loader::before {
  content: ''; position: absolute; inset: 0;
  background: var(--color-bg);
  transition: opacity .75s var(--ease-inout);
}
.loader.done { pointer-events: none; }
.loader.done::before { opacity: 0; }
.loader-inner {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 18px;
}
.loader-logo { transition: opacity .45s var(--ease-out), transform .8s var(--ease-inout); }
.loader.done .loader-logo { opacity: 0; transform: scale(.86); }
.loader-logo .ring {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: ring-draw 1.1s var(--ease-inout) .05s forwards;
}
.loader-logo path { opacity: 0; animation: fade-in .7s var(--ease-out) .45s forwards; }
@keyframes ring-draw { to { stroke-dashoffset: 0; } }
@keyframes fade-in { to { opacity: 1; } }

.loader-wordmark {
  line-height: 1;
  transform-origin: center center;
  transition: transform .9s var(--ease-inout);
  will-change: transform;
  animation: rise-in .9s var(--ease-out) .15s backwards;
}
@keyframes rise-in { from { opacity: 0; transform: translateY(14px); } }
/* posé : le nom du loader s'efface pendant que le dock se révèle, même
   durée, même endroit — un fondu croisé, jamais une bascule sèche */
.loader-wordmark.landed { opacity: 0; transition: opacity .32s var(--ease-out); }
.loader-rule {
  display: block; width: 120px; height: 1px;
  background: color-mix(in srgb, var(--color-text) 16%, transparent);
  overflow: hidden;
  transition: opacity .3s var(--ease-out), transform .5s var(--ease-inout);
}
.loader.done .loader-rule { opacity: 0; transform: scaleX(.4); }
.loader-rule i {
  display: block; width: 100%; height: 100%;
  background: var(--color-accent);
  transform: scaleX(0); transform-origin: left;
}

/* ═══════════ DOCK ═══════════ */
.dock {
  transform: translate(-50%, -180%);
  transition: transform .9s var(--ease-out) .15s, opacity .32s var(--ease-out), box-shadow .5s;
}
body.is-ready .dock { transform: translate(-50%, 0); }
/* pendant le relais le dock est déjà à sa place, simplement invisible */
body.handoff .dock { transform: translate(-50%, 0); opacity: 0; transition: none; }

.nav-link { position: relative; transition: color .3s; }
.nav-link::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: -4px;
  height: 1.5px; border-radius: 2px; background: currentColor;
  transform: scaleX(0); transform-origin: right;
  transition: transform .45s var(--ease-inout);
}
.nav-link:hover::after, .nav-link.is-active::after { transform: scaleX(1); transform-origin: left; }
.ig-link { transition: background .3s, transform .4s var(--ease-out); }
.ig-link:hover { transform: rotate(-8deg) scale(1.06); }

/* boutons : un souffle au survol, un appui au clic */
.btn { transition: background .3s, border-color .3s, transform .45s var(--ease-out), box-shadow .45s var(--ease-out); }
.btn:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.btn:active { transform: translateY(0) scale(.97); box-shadow: none; transition-duration: .12s; }
.dock .btn:hover { box-shadow: none; }

/* ═══════════ HERO — entrée ═══════════ */
.fl {
  position: absolute;
  /* taille bornée par la largeur ET la hauteur de l'écran : les colonnes
     ne se chevauchent jamais, même sur un écran large et bas */
  --fw: calc(var(--s) * min(1.3px, 0.1015625vw, 0.165vh));
  width: var(--fw);
  aspect-ratio: 1;
  /* plafond de sécurité : jamais coupé en bas */
  top: min(var(--y), calc(100% - var(--fw) - 34px));
  border-radius: var(--r);
  overflow: hidden;
  will-change: transform, opacity;
  clip-path: inset(100% 0 0 0 round var(--r));
  transition: clip-path 1.3s var(--ease-inout);
  transition-delay: calc(var(--fi, 0) * 110ms + .2s);
}
/* nuage SYMÉTRIQUE : côté gauche ancré à gauche, côté droit en miroir
   ancré à droite. Colonne extérieure à 3 %, intérieure à 20 % : la
   première finit au plus à 18 % de la largeur, la seconde au plus à
   31 % — elles ne se touchent pas, et le titre commence au-delà de 33 %. */
.fl.l { left: var(--x); }
.fl.r { right: var(--x); }
.fl.o1 { --x: 3%;  --y: 11%; }
.fl.i1 { --x: 20%; --y: 31%; }
.fl.o2 { --x: 3%;  --y: 55%; }
.fl.i2 { --x: 20%; --y: 74%; }
/* écran étroit : le titre occupe presque toute la largeur — les visuels
   passent dans une bande haute et une bande basse, toujours en miroir */
@media (max-width: 820px) {
  .fl { --fw: calc(var(--s) * 0.1vw + 10px); }
  /* bande haute : sous le dock ; bande basse : ancrée au bas de l'écran */
  .fl.o1 { --x: 3%;  top: calc(env(safe-area-inset-top, 0px) + 92px); }
  .fl.i1 { --x: 26%; top: calc(env(safe-area-inset-top, 0px) + 78px); }
  /* bande basse = MIROIR exact de la bande haute : mêmes tailles, et les
     bords bas à 92 px (extérieur) / 78 px (intérieur) du bas de l'écran,
     comme les bords hauts à 92 / 78 px du haut */
  .fl.o2 { --s: 150 !important; --x: 3%;  top: calc(100% - var(--fw) - 92px - env(safe-area-inset-bottom, 0px)); }
  .fl.i2 { --x: 26%; top: calc(100% - var(--fw) - 78px - env(safe-area-inset-bottom, 0px)); }
}
.fl img {
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.35);
  transition: transform 1.8s var(--ease-out);
  transition-delay: calc(var(--fi, 0) * 110ms + .2s);
}
body.is-ready .fl { clip-path: inset(0 0 0 0 round var(--r)); }
body.is-ready .fl img { transform: scale(1); }

.hero-logo .ring { stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 1.4s var(--ease-inout) .1s; }
.hero-logo .bump { opacity: 0; transition: opacity .9s var(--ease-out) .6s; }
body.is-ready .hero-logo .ring { stroke-dashoffset: 0; }
body.is-ready .hero-logo .bump { opacity: 1; }

.hero-in {
  opacity: 0; transform: translateY(18px);
  transition: opacity 1s var(--ease-out), transform 1.1s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 110ms + .2s);
}
body.is-ready .hero-in { opacity: 1; transform: none; }

/* titre : chaque mot monte derrière sa ligne de base */
.hw {
  display: inline-block;
  padding-bottom: .14em; margin-bottom: -.14em;
  clip-path: inset(-.4em -.3em 0 -.3em);
}
.hw > span {
  display: inline-block;
  transform: translateY(115%);
  transition: transform 1.15s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms + .45s);
}
body.is-ready .hw > span { transform: none; }

/* le logo et le titre remontent d'un cran au-dessus du centre */
#heroCopy { transform: translateY(-4vh); }
#heroBrand, #heroTitle { will-change: transform, opacity, filter; }
.studio { opacity: 0; clip-path: inset(50% 50% 50% 50%); will-change: clip-path, opacity; }
#studioImg { will-change: transform; transform-origin: 50% 50%; }

/* paragraphe « About » : les mots s'encrent au scroll */
.aw { display: inline-block; margin-right: 0.24em; opacity: .22; will-change: opacity, transform; }
.aw.hl { color: var(--color-accent-300); }
#aboutText, #aboutPortrait { will-change: transform, opacity; }
/* téléphone : le portrait devient un cercle posé AU-DESSUS du texte, qui
   reprend toute la largeur — même logique que la section Bio */
@media (max-width: 700px) {
  #about {
    flex-direction: column-reverse !important;
    justify-content: center !important;
    align-items: flex-start !important;
    gap: 26px !important;
    padding: 76px 24px 28px !important;
  }
  #aboutPortrait {
    width: clamp(120px, 36vw, 170px) !important;
    aspect-ratio: 1 !important;
    border-radius: 50% !important;
  }
  #aboutText { gap: 18px !important; width: 100%; }
  #aboutWords { max-width: none !important; font-size: clamp(25px, 7.4vw, 32px) !important; }
}

/* ═══════════ RÉVÉLATIONS GÉNÉRIQUES ═══════════ */
.reveal {
  opacity: 0; transform: translateY(28px);
  transition: opacity 1s var(--ease-out), transform 1.1s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.reveal.in-view { opacity: 1; transform: none; }
.reveal-rise { transform: translateY(60px) scale(.97); transform-origin: 50% 100%; }

/* titres : mot par mot, masqués par leur propre ligne */
.rw {
  display: inline-block;
  padding-bottom: .16em; margin-bottom: -.16em;
  clip-path: inset(-.5em -.4em 0 -.4em);
}
.rw > .rwi {
  display: inline-block;
  transform: translateY(110%);
  transition: transform 1.1s var(--ease-out);
  transition-delay: calc(var(--wi, 0) * 60ms);
}
.reveal-lines.in-view .rw > .rwi { transform: none; }
/* une fois posé, plus aucun masque (l'ovale dessiné déborde du mot) */
.reveal-lines.settled .rw { clip-path: none; }

.reveal-pop {
  opacity: 0; transform: scale(.82) rotate(-6deg);
  transition: opacity 1s var(--ease-out), transform 1.4s var(--ease-out);
}
.reveal-pop.in-view { opacity: 1; transform: none; }
.reveal-pop img { transform: scale(1.25); transition: transform 1.8s var(--ease-out); }
.reveal-pop.in-view img { transform: scale(1); }

/* ═══════════ WORK ═══════════ */
/* les cartes (et le calendrier) arrivent de biais : en défilement natif
   (téléphone) elles débordaient à droite et la page glissait de côté.
   `clip` coupe le débord sans créer de zone de défilement. */
#work, #talk { overflow-x: clip; }
/* grille toujours symétrique : 3 × 2 ou 2 × 3 (1 colonne sur téléphone),
   jamais un 4 + 2 */
.tracks { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 959px) { .tracks { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 559px) { .tracks { grid-template-columns: minmax(0, 1fr); } }
.track { will-change: transform; }
.track iframe { transition: box-shadow .5s var(--ease-out), transform .6s var(--ease-out); }
.track:hover iframe { box-shadow: var(--shadow-lg); transform: translateY(-4px); }

/* lecteurs SoundCloud : sur écran tactile, un voile transparent couvre
   l'illustration et laisse un trou sur le bouton lecture — toucher l'image
   ne lance plus la musique ; le bouton et la barre de lecture restent
   actifs, et glisser sur l'image fait défiler la page */
.sc-wrap { position: relative; }
.sc-shield { display: none; }
@media (hover: none), (pointer: coarse) {
  .sc-shield {
    display: block;
    /* le voile s'arrête au-dessus de la barre de lecture (forme d'onde,
       ~38-74 px du bas) : on peut toujours avancer dans le morceau */
    position: absolute; inset: 0 0 84px 0; z-index: 2;
    clip-path: polygon(evenodd,
      0 0, 100% 0, 100% 100%, 0 100%, 0 0,
      var(--hx0) var(--hy0), var(--hx0) var(--hy1), var(--hx1) var(--hy1), var(--hx1) var(--hy0), var(--hx0) var(--hy0));
    /* le bouton lecture du lecteur visuel : ~11-54 px × 16-59 px */
    --hx0: 4px; --hy0: 8px; --hx1: 62px; --hy1: 66px;
  }
}

/* ═══════════ PROCESS ═══════════ */
.proc-panel { will-change: transform; transform-origin: 50% 0; }
.proc-in { will-change: opacity, transform; }
.step-head, .step-text, .motif { will-change: opacity, transform; }
.step-head:not(:first-child), .step-text:not(:first-child), .motif:not(:first-child) { opacity: 0; }
#procCta { will-change: transform; }
.step-pill { position: relative; cursor: pointer; }
/* zone de clic agrandie : les pastilles servent de navigation */
.step-pill::before { content: ''; position: absolute; inset: -14px -4px; }
/* plus de scène épinglée : la section fait un écran, le carrousel se pilote
   aux flèches / pastilles (et au doigt sur téléphone) */
.s-process { height: auto !important; }

/* ordinateur : le groupe « mandala + numéro/titre » et le texte d'étape est
   CENTRÉ entre les deux flèches. Deux pistes souples (1fr) l'encadrent ;
   l'en-tête et le pied gardent toute la largeur du panneau. */
@media (min-width: 701px) {
  #procPanel {
    grid-template-columns: minmax(0, 1fr) auto auto minmax(0, 1fr) !important;
    column-gap: 0 !important;
  }
  #procPanel > div:nth-child(1) { grid-column: 1 / -1; grid-row: 1; }
  #procPanel > div:nth-child(2) { grid-column: 2; grid-row: 2; }
  #procPanel > div:nth-child(3) { grid-column: 3; grid-row: 2; margin-left: clamp(48px, 6.5vw, 120px); }
  #procPanel > div:nth-child(4) { grid-column: 1 / -1; grid-row: 3; }
}

/* flèches de carrousel, façon Instagram : petits ronds clairs aux bords */
.car-arrow {
  position: absolute; top: 50%; z-index: 5;
  width: 38px; height: 38px; margin-top: -19px;
  display: flex; align-items: center; justify-content: center;
  padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: color-mix(in oklch, var(--color-bg) 92%, transparent);
  color: var(--color-accent-2-800);
  box-shadow: var(--shadow-md);
  transition: opacity .35s var(--ease-out), transform .45s var(--ease-out), background .3s;
}
.car-prev { left: clamp(14px, 1.8vw, 26px); }
.car-next { right: clamp(14px, 1.8vw, 26px); }
.car-arrow:hover { background: var(--color-bg); transform: scale(1.08); }
.car-arrow:active { transform: scale(.94); transition-duration: .12s; }
.car-arrow.is-off { opacity: 0; pointer-events: none; transform: scale(.8); }
.car-arrow:focus-visible { outline: 2px solid var(--color-accent-300); outline-offset: 3px; }

/* téléphone : plus de scène épinglée — les 4 étapes deviennent un carrousel
   qu'on fait glisser à gauche / à droite. La mise en page passe sur une
   colonne : en-tête, motif + titre d'étape, texte, pastilles + CTA. */
@media (max-width: 700px) {
  .s-process .pin { height: auto !important; transform: none !important; }
  /* téléphone : on glisse au doigt, pas de flèches (comme l'appli Instagram) */
  .car-arrow { display: none; }
  #procPanel {
    height: auto !important;
    grid-template-columns: minmax(0, 1fr) !important;
    grid-template-rows: auto !important;
    padding: 72px 22px 34px !important;
    gap: 26px !important;
    border-radius: calc(var(--radius-lg) * 1.6) !important;
    touch-action: pan-y;
    user-select: none; -webkit-user-select: none;
  }
  #procPanel h2 { font-size: clamp(30px, 8.6vw, 40px) !important; }
  /* motif à gauche, numéro + titre à droite, sur une ligne */
  #procPanel > div:nth-child(2) {
    flex-direction: row !important;
    align-items: center !important;
    gap: 18px !important;
    align-self: stretch !important;
  }
  #procPanel .motifs { width: 84px !important; height: 84px !important; flex: none; }
  #procPanel > div:nth-child(2) > div:last-child { flex: 1; min-width: 0; }
  /* numéro au-dessus du titre d'étape : côte à côte ils débordent du panneau */
  .step-head { flex-direction: column !important; align-items: flex-start !important; gap: 2px !important; }
  .step-head span { font-size: 42px !important; }
  .step-head h3 { font-size: clamp(26px, 7.8vw, 32px) !important; }
  #procPanel > div:nth-child(3) { align-self: start !important; }
  .step-text { max-width: none !important; font-size: clamp(21px, 6vw, 26px) !important; line-height: 1.25 !important; }
  /* pied : pastilles + note, puis le CTA centré (son ovale a la place) */
  #procPanel > div:nth-child(4) {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 30px !important;
  }
  #procPanel > div:nth-child(4) > div:first-child { flex-direction: column !important; align-items: flex-start !important; gap: 14px !important; }
  #procCta { align-self: center; }
}

/* ═══════════ TALK ═══════════ */
.talk-ink .hv { opacity: .22; will-change: opacity, transform; }
.talk-cal { will-change: transform, opacity; transform-origin: 50% 100%; }
body.static .talk-ink .hv { opacity: 1; }

#readyLink svg { will-change: transform; }

/* ═══════════ BIO ═══════════ */
#bio { will-change: transform; }
#bioBg { will-change: transform; }

/* ═══════════ FAQ ═══════════ */
.faq { transition: opacity 1s var(--ease-out), transform 1.1s var(--ease-out), background .35s, box-shadow .5s var(--ease-out); }
.faq:hover { box-shadow: var(--shadow-md); }
.faq.is-animating { overflow: hidden; }
.faq-plus { transition: transform .55s var(--ease-inout), background .3s; }
.faq summary:hover .faq-plus { transform: rotate(90deg); }
.faq[open] .faq-plus { transform: rotate(45deg); }
.faq[open] summary:hover .faq-plus { transform: rotate(135deg); }
.faq > p { transition: opacity .5s var(--ease-out) .08s, transform .6s var(--ease-out) .08s; }
.faq.is-closing > p, .faq.is-opening > p { opacity: 0; transform: translateY(-8px); }
.faq.is-opening.is-expanded > p { opacity: 1; transform: none; }

/* ═══════════ FOOTER ═══════════ */
.footer-mail { display: inline-block; align-self: flex-start; transition: color .3s; }
.footer-mail-text { position: relative; }
.footer-mail-text::after {
  content: '';
  position: absolute; left: 0; bottom: -6px;
  width: 100%; height: 1.5px; background: currentColor;
  transform: scaleX(0); transform-origin: right;
  transition: transform .6s var(--ease-inout);
}
.footer-mail:hover .footer-mail-text::after { transform: scaleX(1); transform-origin: left; }

.footer-logo {
  opacity: 0; transform: rotate(-140deg) scale(.5);
  transition: opacity .8s var(--ease-out), transform 1.6s var(--ease-out);
}
.footer-brand.in-view .footer-logo { opacity: 1; transform: none; }
#footerName .ch {
  display: inline-block;
  clip-path: inset(-.3em -.2em -.06em -.2em);
}
#footerName .chi {
  display: inline-block;
  transform: translateY(120%);
  transition: transform 1.1s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 38ms + .1s);
}
.footer-brand.in-view #footerName .chi { transform: none; }

/* ═══════════ SURVOL DU TEXTE ═══════════
   Chaque mot se soulève légèrement sous la souris. On passe par la
   propriété `translate` (et non `transform`) : elle se compose avec les
   transforms posés en continu par le moteur de scroll, sans les écraser. */
.hv { display: inline-block; }
@media (hover: hover) and (pointer: fine) {
  /* un frémissement plutôt qu'un saut : levée minime, aucune rotation,
     montée et retombée lentes et douces */
  .hv, .aw, .rw, .hw, #footerName .ch {
    transition: translate .8s var(--ease-soft);
  }
  .hv:hover { translate: 0 -0.035em; }
  .aw:hover, .rw:hover, .hw:hover, .big-hv .hv:hover { translate: 0 -0.03em; }
  #footerName .ch:hover { translate: 0 -0.04em; }

  /* hero : le conteneur ignore la souris (maquette), mais le logo et les
     mots du titre la reçoivent pour réagir au survol */
  .hero-logo, #heroBrand > span .hv, #heroTitle .hw { pointer-events: auto; }
  .hero-logo { transition: scale 1.1s var(--ease-soft); }
  .hero-logo:hover { scale: 1.025; }
}

/* ═══════════ MOUVEMENT RÉDUIT ═══════════ */
body.static .fl, body.static .fl img,
body.static .hw > span, body.static .hero-in,
body.static .reveal, body.static .rw > .rwi,
body.static .reveal-pop, body.static .reveal-pop img,
body.static .footer-logo, body.static #footerName .chi { opacity: 1; transform: none; clip-path: none; transition: none; }
body.static .hero-logo .ring { stroke-dashoffset: 0; }
body.static .hero-logo .bump { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}
