/* ============================================
   MATHEO DELANNOY — couche motion v2.1
   Langage d'animation + sequence d'ouverture + arrivee au scroll.
   Se charge apres theme.css et ne decrit que des mouvements.

   Unite : 80ms. Durees en Fibonacci sur cette unite : 2 3 5 8 13.
   Deux cadences : 80 (jalons) et 40 (series).
   Cinq courbes, chacune sur son terrain.

   DEUX TEMPS, PAS UN :
     .md-play  l'esquisse se trace, au noir. C'est l'ecran de chargement.
     .md-go    le contenu arrive. Pose seulement quand les images du premier
               module sont vraiment pretes — c'est motion.js qui decide.
     .md-ink   l'esquisse se retire au gris. Elle ne le fait qu'une fois le
               contenu la, donc le noir signale « ca charge » et le gris
               signale « c'est pret ».
   ============================================ */

:root {
  /* --- durees --- */
  --t-1: 160ms;   /* survol, changement d'etat */
  --t-2: 240ms;   /* une ligne de menu */
  --t-3: 400ms;   /* un bloc de contenu */
  --t-4: 640ms;   /* un filet, le nom, une image */
  --t-5: 1040ms;  /* transition de page (home <-> info) */

  /* --- cadences --- */
  --step: 80ms;
  --step-tight: 40ms;

  /* --- courbes ---
     La courbe suit la PROPRIETE, pas l'element. Un deplacement se lit dans
     l'espace, une opacite non : la meme courbe qui rend un mouvement elegant
     rend un fondu brutal. */
  --ease-line: cubic-bezier(.1, .1, .7, 1);   /* ce qui se trace : part a vitesse
                                                 constante (y1 = x1 force la pente
                                                 initiale a 1), se pose en fin */
  --ease-fade: cubic-bezier(.4, 0, .6, 1);    /* ce qui apparait, et le flou qui
                                                 se resorbe */
  --ease-ink:  linear;                        /* ce qui se retire : une interpolation
                                                 de couleur ne supporte aucune
                                                 inflexion, elle se lirait comme
                                                 un a-coup */
  --ease-move: cubic-bezier(.65, 0, .35, 1);  /* ce qui se deplace : dot, survols */
  --ease-in:   cubic-bezier(.7, 0, .84, 0);   /* ce qui sort */

  /* --- partition de l'ouverture --- */
  --sketch-dur: 640ms;   /* duree de trace d'un filet */
  --ink-dur: 640ms;      /* duree du retrait noir -> gris */
}

/* Sans JS, html.motion n'est jamais pose : le site se comporte comme avant. */

/* Le fondu global de 500ms sur <body> n'a plus lieu d'etre : la sequence
   fait apparaitre les elements un par un. */
html.motion body { transition: none !important; }

@keyframes md-draw-x { from { transform: scaleX(0) } to { transform: scaleX(1) } }
@keyframes md-draw-y { from { transform: scaleY(0) } to { transform: scaleY(1) } }
@keyframes md-fade   { from { opacity: 0 }          to { opacity: 1 } }
@keyframes md-on     { from, to { opacity: 1 } }

/* ============================================
   ACTE 1 — L'ESQUISSE (et l'ecran de chargement)
   ============================================ */

html.motion body.md-arm .hline-top,
html.motion body.md-arm .divider-h-left,
html.motion body.md-arm .divider-h-mid,
html.motion body.md-arm .divider-h-right,
html.motion body.md-arm .hline-bottom { transform: scaleX(0); }
html.motion body.md-arm .vline-1,
html.motion body.md-arm .vline-2 { transform: scaleY(0); }

html.motion body.md-play .hline-top,
html.motion body.md-play .hline-bottom,
html.motion body.md-play .divider-h-left,
html.motion body.md-play .divider-h-mid,
html.motion body.md-play .divider-h-right {
  transform-origin: left center;
  background-color: #000;
  animation: md-draw-x var(--md-dur) var(--md-seg-ease, var(--ease-line)) var(--md-d) both;
}
html.motion body.md-play .vline-1,
html.motion body.md-play .vline-2 {
  transform-origin: center top;
  background-color: #000;
  animation: md-draw-y var(--md-dur) var(--ease-line) var(--md-d) both;
}

/* Le retrait est une TRANSITION, pas une animation : il ne peut donc pas
   entrer en conflit avec le trace, qui occupe deja la propriete animation.
   Les cinq traits virent au gris ensemble — c'est l'esquisse qui a fini son
   travail, pas cinq objets qui changent de couleur. */
html.motion body.md-ink .hline-top,
html.motion body.md-ink .hline-bottom,
html.motion body.md-ink .divider-h-left,
html.motion body.md-ink .divider-h-mid,
html.motion body.md-ink .divider-h-right,
html.motion body.md-ink .vline-1,
html.motion body.md-ink .vline-2 {
  background-color: var(--color-grey);
  transition: background-color var(--ink-dur) var(--ease-ink);
}

/* ============================================
   ACTE 2 — LE CONTENU
   Les delais sont comptes depuis .md-go, pas depuis le chargement : si les
   images tardent, toute la partition glisse ensemble.
   ============================================ */

/* Deux couches, deux dependances :
     .md-nav  le cadre et la navigation. Ils n'ont aucune raison d'attendre
              les images, donc ils partent avec l'esquisse.
     .md-in   ce qui appartient au projet affiche. Ca, ca attend. */
html.motion body.md-arm .md-nav,
html.motion body.md-arm .md-in { opacity: 0; }
html.motion body.md-play:not(.md-go) .md-in { opacity: 0; }
html.motion body.md-arm .project-content,
html.motion body.md-play:not(.md-go) .project-content { opacity: 0; }

html.motion body.md-play .md-nav {
  animation: md-fade var(--md-dur) var(--ease-fade) var(--md-d) both;
}

/* Opacite pure, aucun deplacement : le filet est la seule chose qui bouge.
   Une animation l'emporte sur une declaration normale, donc ces regles
   passent devant les .visible poses par main.js et devant le style inline
   d'opacite de la description. */
html.motion body.md-go .md-in {
  animation: md-fade var(--md-dur) var(--ease-fade) var(--md-d) both;
}

/* Le bloc image n'est pas en fondu : il arrive opaque et flou, et c'est le
   flou qui se resorbe (voir motion.js). */
html.motion body.md-go .project-content {
  animation: md-fade 1ms linear var(--md-content-at) both;
}

/* La legende : motion.js en fait des lignes qui ont chacune leur fondu, donc
   c'est le conteneur qu'il faut ouvrir — et l'ouvrir franchement, sans le
   moindre palier a zero. Sans ca, main.js le garde a zero jusqu'a ce qu'il
   pose .visible, et toute la sequence des lignes se joue derriere un rideau. */
html.motion body.md-play .project-tags {
  animation: md-on 1ms linear both;
}

/* ============================================
   LE FLOU
   Un canevas se superpose exactement au MODULE — pas a chaque image. Sur un
   diptyque, le flou traverse donc la jointure au lieu de s'arreter net au
   milieu. Le canevas se retire quand le rayon atteint zero.
   Aucun zoom : voir motion.js, le debord se fait en prolongeant les pixels
   de bord, pas en agrandissant l'image.
   ============================================ */

/* Le conteneur du flou : il epouse le module et recadre le canevas, qui lui
   depasse de PAD de chaque cote. C'est ce debord qui protege les bords du
   flou — sans jamais toucher a l'echelle de l'image. */
.md-blur {
  position: absolute;
  inset: 0;
  z-index: 2;
  overflow: hidden;
  pointer-events: none;
}

/* Un module en attente d'arrivee au scroll reste masque : sans ca on verrait
   l'image nette une fraction de seconde avant que le flou ne se pose. */
html.motion .md-hold > :not(.md-blur) { visibility: hidden; }

/* ============================================
   FIN DE SEQUENCE
   On retire toutes les animations : les elements repassent sous le controle
   de theme.css et de main.js — notamment .visible, qui doit pouvoir les
   recacher au changement de projet.
   ============================================ */

html.motion body.md-done .md-nav,
html.motion body.md-done .md-in,
html.motion body.md-done .project-content,
html.motion body.md-done .project-tags,
html.motion body.md-done .hline-top,
html.motion body.md-done .hline-bottom,
html.motion body.md-done .vline-1,
html.motion body.md-done .vline-2,
html.motion body.md-done .divider-h-left,
html.motion body.md-done .divider-h-mid,
html.motion body.md-done .divider-h-right { animation: none; }

/* --- retour dans la session : pas d'ouverture, un simple fondu --- */
html.motion body.md-short { animation: md-fade var(--t-2) var(--ease-fade) both; }

/* --- accessibilite --- */
@media (prefers-reduced-motion: reduce) {
  html.motion body.md-play .hline-top,
  html.motion body.md-play .hline-bottom,
  html.motion body.md-play .vline-1,
  html.motion body.md-play .vline-2,
  html.motion body.md-play .divider-h-left,
  html.motion body.md-play .divider-h-mid,
  html.motion body.md-play .divider-h-right,
  html.motion body.md-play .md-nav,
  html.motion body.md-play .project-tags,
  html.motion body.md-go .md-in,
  html.motion body.md-go .project-content {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
  }
  html.motion .md-hold > :not(.md-blur) { visibility: visible; }
}

/* ============================================
   CORRECTIONS HORS MOTION
   A remonter dans theme.css a la prochaine passe — c'est ici uniquement
   parce que motion.css se charge apres et coute 6 Ko au lieu de 32.
   ============================================ */

/* Vimeo letterboxe la video dans son lecteur : le debord de 1px du theme ne
   suffit pas toujours a cacher la bande noire, d'ou le lisere en haut du
   module. Un debord proportionnel tient a toutes les largeurs. */
.project-video--vimeo iframe {
  top: -1%;
  height: 102%;
}
