/* ==========================================================================
   Morris & Chapman — Motion
   Le morph de page vit dans mc-view-transitions.css ; ici le reste.
   ========================================================================== */

/* ==========================================================================
   HERO HOME
   Temps 1 : « Your policy messages » se révèle lettre à lettre, de gauche
             à droite.
   Temps 2 : un seul mot occupe la 2e ligne et se remplace — delivered →
             seen → understood — chaque mot entrant descendant du haut en
             se redressant (mécanique Glacier).

   Rien ne s'applique tant que .mc-hero-ready n'est pas posée par le JS :
   si le JS échoue, le titre s'affiche normalement. Jamais de texte
   invisible.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Réglages
   -------------------------------------------------------------------------- */
.root-heading.mc-hero-ready {
	--mc-ease:        cubic-bezier( 0.22, 1, 0.36, 1 );

	/* Temps 1 — la frappe */
	/* Le rapport dur / step = combien de lettres fondent EN MÊME TEMPS.
	   À 26ms / 0.5s elles étaient 19 : on voyait un dégradé balayer la
	   ligne, pas des lettres apparaître. À 55ms / 0.45s elles sont ~8,
	   et la transparence de chacune se lit.
	   Écarte le pas pour détacher les lettres, allonge la durée pour
	   rendre chaque fondu plus doux. */
	--mc-char-step:   55ms;    /* écart entre deux lettres */
	--mc-char-dur:    0.45s;   /* durée d'apparition d'une lettre */
	--mc-char-rise:   0.5em;   /* d'où elle monte */

	/* Temps 2 — la rotation des mots */
	--mc-rot-dur:     0.75s;   /* durée d'un remplacement */
	--mc-rot-offset:  115%;    /* distance hors du masque */

	/* Inclinaison. À 0 le mouvement est une descente verticale franche.
	   Toute valeur > 0 fait basculer la lecture vers "tambour qui tourne",
	   parce que le mot pivote pendant qu'il traverse le masque. */
	--mc-rot-tilt:    0deg;

	/* Marge basse du masque, réservée aux jambages (g, y, p, q, j).
	   Aucun des trois mots actuels n'en a, donc 0 : toute valeur > 0 crée
	   une fenêtre sous la ligne par laquelle le mot SORTANT reste visible.
	   Si tu changes un mot pour un mot à jambage, passe à 0.18em ET monte
	   --mc-rot-offset d'autant (sinon le défaut réapparaît). */
	--mc-rot-pad:     0em;
}

/* --------------------------------------------------------------------------
   Neutralisation de l'effet d'origine du thème

   style.css fait déjà partir .main à opacity:0 avec un fadeIn de 1,5 s, et
   colore les mots via une keyframe colorFade attachée à .word. Les deux
   entrent en conflit avec la frappe et le rotateur : on les désamorce, mais
   UNIQUEMENT quand notre effet est actif (.mc-hero-ready), pour que le
   comportement d'origine reprenne si le JS ne tourne pas.
   -------------------------------------------------------------------------- */
.root-heading.mc-hero-ready .main {
	opacity: 1;
	animation: none;
}

/* --mc-end-color est déjà posé par .root-heading .word1/2/3 dans style.css :
   on s'y branche pour garder les couleurs de service, une par mot. */
.mc-rot-item {
	color: var( --end-color, inherit );
}

/* --------------------------------------------------------------------------
   Temps 1 — la frappe
   Les mots restent des blocs (.mc-w) pour que le retour à la ligne se fasse
   entre les mots et jamais au milieu d'un mot.
   -------------------------------------------------------------------------- */
.root-heading.mc-hero-ready .mc-w {
	display: inline-block;
	white-space: nowrap;
}

.root-heading.mc-hero-ready .mc-c {
	display: inline-block;
	opacity: 0;
	translate: 0 var( --mc-char-rise );
	will-change: opacity, transform;
}

.root-heading.mc-hero-in .mc-c {
	opacity: 1;
	translate: 0 0;
	transition:
		opacity   var( --mc-char-dur ) ease            calc( var( --mc-ci, 0 ) * var( --mc-char-step ) ),
		translate var( --mc-char-dur ) var( --mc-ease ) calc( var( --mc-ci, 0 ) * var( --mc-char-step ) );
}

/* --------------------------------------------------------------------------
   Temps 2 — le rotateur de mots
   Largeur et hauteur posées par le JS (le mot le plus large), sinon la
   ligne sauterait à chaque changement.
   -------------------------------------------------------------------------- */
.mc-rotator {
	position: relative;
	display: inline-block;
	box-sizing: content-box;   /* la hauteur posée par le JS est celle du texte */
	vertical-align: bottom;
	overflow: hidden;

	padding-bottom: var( --mc-rot-pad );
	margin-bottom: calc( var( --mc-rot-pad ) * -1 );
}

.mc-rot-item {
	position: absolute;
	left: 0;
	top: 0;
	white-space: nowrap;
	will-change: transform;

	/* au repos : au-dessus, penché */
	translate: 0 calc( var( --mc-rot-offset ) * -1 );
	rotate: calc( var( --mc-rot-tilt ) * -1 );
}

/* le mot en place */
.mc-rot-item.is-active {
	translate: 0 0;
	rotate: 0deg;
	transition:
		translate var( --mc-rot-dur ) var( --mc-ease ),
		rotate    var( --mc-rot-dur ) var( --mc-ease );
}

/* le mot qui s'en va — il continue vers le bas */
.mc-rot-item.is-leaving {
	translate: 0 var( --mc-rot-offset );
	rotate: var( --mc-rot-tilt );
	transition:
		translate var( --mc-rot-dur ) var( --mc-ease ),
		rotate    var( --mc-rot-dur ) var( --mc-ease );
}

/* Chaque mot garde sa couleur de service (word1/2/3 existants). */

/* --------------------------------------------------------------------------
   Rejouer la séquence
   Le titre s'efface en bloc, on remet tout à zéro pendant qu'il est
   invisible, puis la frappe repart. .mc-hero-noanim coupe toute transition
   le temps de la remise à zéro, sinon on verrait les lettres revenir en
   arrière et les mots remonter.
   -------------------------------------------------------------------------- */
.root-heading.mc-hero-out {
	opacity: 0;
	transition: opacity 0.45s ease;
}

.root-heading.mc-hero-noanim,
.root-heading.mc-hero-noanim * {
	transition: none !important;
}

/* --------------------------------------------------------------------------
   Le CTA suit
   -------------------------------------------------------------------------- */
.mc-hero-cta { opacity: 0; translate: 0 1rem; }

.mc-hero-in-cta .mc-hero-cta {
	opacity: 1;
	translate: 0 0;
	transition:
		opacity 0.6s ease 0.7s,
		translate 0.6s cubic-bezier( 0.22, 1, 0.36, 1 ) 0.7s;
}

/* --------------------------------------------------------------------------
   Accessibilité — rien ne bouge, et le premier mot reste affiché.
   -------------------------------------------------------------------------- */
@media ( prefers-reduced-motion: reduce ) {
	.root-heading.mc-hero-ready .mc-c { opacity: 1; translate: none; transition: none; }
	.mc-rot-item { transition: none !important; }
	.mc-rot-item:not(.is-active) { visibility: hidden; }
	.mc-rot-item.is-active { translate: none; rotate: none; }
	.mc-hero-cta { opacity: 1; translate: none; }
}

/* ==========================================================================
   RÉVÉLATION AU DÉFILEMENT
   Les blocs de contenu montent légèrement en apparaissant.

   Rien ne s'applique tant que .mc-reveal-ready n'est pas posée par le JS :
   si le JS échoue ou ne se charge pas, la page s'affiche normalement.
   Jamais de contenu invisible.
   ========================================================================== */

:root {
	--mc-rev-dist:  24px;    /* distance de la remontée */
	--mc-rev-dur:   0.7s;    /* durée */
	--mc-rev-step:  60ms;    /* décalage entre tuiles d'une même grille */
	--mc-rev-ease:  cubic-bezier( 0.22, 1, 0.36, 1 );
}

.mc-reveal-ready .mc-rev {
	opacity: 0;
	translate: 0 var( --mc-rev-dist );
	will-change: opacity, transform;
}

.mc-reveal-ready .mc-rev.mc-in {
	opacity: 1;
	translate: 0 0;
	transition:
		opacity   var( --mc-rev-dur ) ease                 calc( var( --mc-ri, 0 ) * var( --mc-rev-step ) ),
		translate var( --mc-rev-dur ) var( --mc-rev-ease )  calc( var( --mc-ri, 0 ) * var( --mc-rev-step ) );
}

/* Une fois révélé, on libère le compositeur. */
.mc-reveal-ready .mc-rev.mc-done {
	will-change: auto;
}

@media ( prefers-reduced-motion: reduce ) {
	.mc-reveal-ready .mc-rev {
		opacity: 1;
		translate: none;
		transition: none;
	}
}

/* ==========================================================================
   FRAPPE SUR LES TITRES COLLANTS
   Même mécanique que le hero de la home, appliquée aux blocs de titre des
   pages Services et des case studies.

   Sans danger pour position:sticky : on transforme les LETTRES, donc des
   descendants du module collant. Seule une transformation sur un ANCÊTRE
   casserait le collant.
   ========================================================================== */

.mc-typed .mc-tw {
	display: inline-block;
	white-space: nowrap;
}

.mc-typed .mc-tc {
	display: inline-block;
	opacity: 0;
	translate: 0 var( --mc-char-rise, 0.5em );
	will-change: opacity, transform;
}

.mc-typed.mc-typed-in .mc-tc {
	opacity: 1;
	translate: 0 0;
	transition:
		opacity   var( --mc-char-dur, 0.45s ) ease
		          calc( var( --mc-ci, 0 ) * var( --mc-tstep, 55ms ) ),
		translate var( --mc-char-dur, 0.45s ) cubic-bezier( 0.22, 1, 0.36, 1 )
		          calc( var( --mc-ci, 0 ) * var( --mc-tstep, 55ms ) );
}

@media ( prefers-reduced-motion: reduce ) {
	.mc-typed .mc-tc {
		opacity: 1;
		translate: none;
		transition: none;
	}
}

/* --------------------------------------------------------------------------
   Révélation instantanée, sans animation.
   Sert quand le titre entre dans l'écran en REMONTANT : l'effet ne joue
   qu'à la descente, mais rien ne doit jamais rester invisible.
   -------------------------------------------------------------------------- */
.mc-typed.mc-typed-now .mc-tc {
	opacity: 1;
	translate: none;
	transition: none;
}

/* ==========================================================================
   LISTES DE SERVICES — fond au survol et au passage
   --------------------------------------------------------------------------
   Markup produit par display_services_list() :
     .services-list > ul > li > h3 > span.number  +  span.description

   DEUX PIÈGES, tous deux relevés sur le site en ligne.

   1. style.css contient sa propre règle :
        .services-list li { padding: calc(var(--mc-global-gap) * 1.5) 0; margin: 0 }
      Elle a EXACTEMENT la même spécificité que la nôtre et elle est chargée
      APRÈS mc-motion.css : à égalité, c'est la dernière qui gagne. Nos
      padding et margin étaient donc ignorés, sans la moindre erreur visible.
      D'où les sélecteurs en `.services-list ul li` ci-dessous : un élément de
      plus suffit à passer devant, sans recourir à !important.

   2. Ces 48 px de marge intérieure verticale sont le rythme voulu par le
      thème, et on n'y touche pas : réduire la mise en page permanente pour
      servir un état qui dure une seconde serait l'inverse du bon ordre.
      Le fond est donc dessiné sur une COUCHE EN RETRAIT (::after) plutôt que
      posé sur l'item : il épouse le texte, l'espacement de la liste ne bouge
      pas d'un pixel.
   ========================================================================== */

:root {
	--mc-li-fond:    rgba( 67, 71, 79, 0.045 );   /* --mc-color-2 très dilué */
	--mc-li-trait:   var( --service-color-2, #517f8a );
	--mc-li-dur:     0.35s;
	--mc-li-air:     1.25rem;   /* débord du fond de part et d'autre du texte */
	--mc-li-retrait: 1.5rem;    /* de combien le fond rentre dans l'item */
}

.services-list ul li {
	position: relative;
	/* Le fond dépasse du texte sans décaler la mise en page :
	   marge intérieure compensée par une marge négative. */
	padding-left:  var( --mc-li-air );
	padding-right: var( --mc-li-air );
	margin-left:  calc( var( --mc-li-air ) * -1 );
	margin-right: calc( var( --mc-li-air ) * -1 );
}

/* La couche de fond. z-index négatif : elle se peint derrière le texte de
   l'item, mais devant le fond de la section. */
.services-list ul li::after {
	content: '';
	position: absolute;
	z-index: -1;
	left: 0;
	right: 0;
	top:    var( --mc-li-retrait );
	bottom: var( --mc-li-retrait );
	background: var( --mc-li-fond );
	opacity: 0;
	transition: opacity var( --mc-li-dur ) ease;
}

/* Trait d'accent à gauche, replié au repos. Il s'aligne sur le fond et non
   sur l'item entier, sinon il dépasserait de 1,5 rem en haut et en bas. */
.services-list ul li::before {
	content: '';
	position: absolute;
	left: 0;
	top:    var( --mc-li-retrait );
	bottom: var( --mc-li-retrait );
	height: auto;
	width: 2px;
	background: var( --mc-li-trait );
	scale: 1 0;
	transform-origin: 50% 0;
	transition: scale var( --mc-li-dur ) cubic-bezier( 0.22, 1, 0.36, 1 );
}

.services-list ul li:hover::after,
.services-list ul li.mc-li-actif::after {
	opacity: 1;
}

.services-list ul li:hover::before,
.services-list ul li.mc-li-actif::before {
	scale: 1 1;
}

@media ( prefers-reduced-motion: reduce ) {
	.services-list ul li::after,
	.services-list ul li::before { transition: none; }
}

/* ==========================================================================
   7. HOVER DES VIGNETTES  (/work/, home, pages service, related)
   --------------------------------------------------------------------------
   Le thème fait déjà un zoom : .media-container:hover img -> scale(1.1).
   Deux choses clochent :
     - il se déclenche sur .media-container seule, pas sur la tuile. Survoler
       le titre révèle la description SANS que l'image bouge.
     - la flèche de .grid-description::after apparaît sans mouvement.
   On reprend donc le zoom au niveau de la tuile et on fait avancer la flèche.
   ========================================================================== */
:root {
	--mc-tuile-zoom:   1.06;    /* 1.1 = valeur d'origine du thème */
	--mc-tuile-dur:    0.7s;
	--mc-tuile-ease:   cubic-bezier( 0.01, 0.21, 0.33, 1 );  /* celui du thème */
	--mc-tuile-fleche: 0.45rem;  /* course de la flèche */
}

/* --- Le média : zoom piloté par la tuile entière --- */
.grid-item .media-container img,
.grid-item .media-container video {
	transform: scale( 1 );
	transition: transform var( --mc-tuile-dur ) var( --mc-tuile-ease );
}

/* Spécificité (0,3,1) : bat le .media-container:hover img (0,2,1) du thème,
   y compris quand on survole l'image directement. */
.grid-item:hover .media-container img,
.grid-item:hover .media-container video,
.grid-item:focus-within .media-container img,
.grid-item:focus-within .media-container video {
	transform: scale( var( --mc-tuile-zoom ) );
}

/* --- La flèche avance --- */
.grid-title .grid-description::after {
	translate: calc( var( --mc-tuile-fleche ) * -1 ) 0;
	transition: translate var( --mc-tuile-dur ) var( --mc-tuile-ease );
}

.grid-item:hover .grid-title .grid-description::after,
.grid-item:focus-within .grid-title .grid-description::after {
	translate: 0 0;
}

/* --- Le titre prend la couleur d'accent ---
   Bloc le plus discutable des trois : supprimer ces 8 lignes suffit. */
.grid-item .grid-title span:not( .grid-description ) {
	transition: color 0.35s ease;
}

.grid-item:hover .grid-title span:not( .grid-description ),
.grid-item:focus-within .grid-title span:not( .grid-description ) {
	color: var( --mc-color-2 );
}

/* --- Garde-fou view transitions ---
   Au clic, le curseur est forcément SUR la tuile : le média est donc zoomé
   au moment où le navigateur photographie la page. Le hero d'arrivée, lui,
   n'est pas zoomé -> le morph partirait d'un cadrage faux.
   mc.viewtransitions.js pose .mc-last-clicked juste avant la capture : on
   remet l'échelle à 1 sans transition, donc dans la même image. */
.grid-item.mc-last-clicked .media-container img,
.grid-item.mc-last-clicked .media-container video {
	transform: none;
	transition: none;
}

@media ( prefers-reduced-motion: reduce ) {
	.grid-item .media-container img,
	.grid-item .media-container video,
	.grid-title .grid-description::after,
	.grid-item .grid-title span:not( .grid-description ) { transition: none; }

	.grid-item:hover .media-container img,
	.grid-item:hover .media-container video { transform: none; }
}

/* ==========================================================================
   8. FIL DE PROGRESSION DE LECTURE
   --------------------------------------------------------------------------
   Posé par mc.motion.js sur les pages assez longues pour que ça ait un sens.
   Couleur : var(--mc-color-2), qui devient la couleur du service sur les
   pages service (voir style.css, body.page-id-xxxx).
   ========================================================================== */
:root {
	--mc-prog-h:    2px;
	--mc-prog-z:    100000;                     /* au-dessus du header Divi */
	--mc-prog-fond: rgba( 67, 71, 79, 0.10 );
}

.mc-progress {
	position: fixed;
	inset: 0 0 auto 0;
	height: var( --mc-prog-h );
	background: var( --mc-prog-fond );
	z-index: var( --mc-prog-z );
	pointer-events: none;
	opacity: 0;
	transition: opacity 0.3s ease;
}

.mc-progress.mc-prog-visible {
	opacity: 1;
}

.mc-progress > span {
	display: block;
	height: 100%;
	background: var( --mc-color-2 );
	transform: scaleX( var( --mc-prog, 0 ) );
	transform-origin: 0 50%;
	will-change: transform;
}

/* Connecté à l'admin : la barre d'admin WordPress est fixe en haut de l'écran
   avec un z-index de 99999. Sans ce décalage, le fil passerait par-dessus
   pendant tout le travail en local. Invisible pour les visiteurs. */
body.admin-bar .mc-progress {
	top: 32px;
}

@media screen and ( max-width: 782px ) {
	body.admin-bar .mc-progress {
		top: 46px;
	}
}

/* ==========================================================================
   9. LE MOT QUI MONTE  —  h2, h3 et gros <p>
   --------------------------------------------------------------------------
   Les h1 gardent la frappe lettre par lettre (bloc plus haut). Ici chaque
   MOT monte de derrière sa propre ligne, avec un décalage d'un mot à l'autre.

   Le masque, c'est le mot lui-même : .mc-tw passe en overflow: clip et les
   lettres qu'il contient démarrent sous son bord inférieur.

   Deux réglages fins à connaître :

   --mc-lift-pad : les jambages (g, p, y) dépassent sous la ligne de base et
     seraient rognés. On ajoute donc du rembourrage en bas. Mais ce
     rembourrage est aussi une fenêtre par laquelle on verrait le mot arriver
     trop tôt — d'où le +100% qui le fait démarrer SOUS cette fenêtre.

   --mc-lift-fix : marge négative SUPPLÉMENTAIRE, à 0 par défaut.
     Je l'avais ajoutée en prévision d'un décalage de ligne de base — un
     inline-block dont overflow n'est pas visible prend son bord inférieur
     comme ligne de base (CSS 2.1 §10.8.1). Mesure faite sur les quatre
     titres d'une case study : avec 0, la hauteur du bloc et la position du
     texte sont identiques au pixel à ce qu'elles sont sans masque. La
     compensation est donc inutile ici, et toute valeur > 0 ne fait que
     tasser le bloc. Laissée en place comme réglage, pas comme correctif.
   ========================================================================== */
:root {
	--mc-lift-pad: 0.28em;
	--mc-lift-fix: 0em;
	--mc-lift-dur: 0.8s;
	--mc-lift-ease: cubic-bezier( 0.22, 1, 0.36, 1 );
}

.mc-lift .mc-tw {
	display: inline-block;
	white-space: nowrap;
	overflow: clip;
	padding-bottom: var( --mc-lift-pad );
	margin-bottom: calc( ( var( --mc-lift-pad ) + var( --mc-lift-fix ) ) * -1 );
}

.mc-lift .mc-tc {
	display: inline-block;
	translate: 0 calc( 100% + var( --mc-lift-pad ) );
	will-change: transform;
}

.mc-lift.mc-lift-in .mc-tc {
	translate: 0 0;
	transition: translate var( --mc-lift-dur ) var( --mc-lift-ease )
	            calc( var( --mc-wi, 0 ) * var( --mc-lstep, 45ms ) );
}

/* Révélation instantanée : titre atteint en REMONTANT, ou mouvement réduit. */
.mc-lift.mc-lift-now .mc-tc {
	translate: none;
	transition: none;
}

@media ( prefers-reduced-motion: reduce ) {
	.mc-lift .mc-tc {
		translate: none;
		transition: none;
	}
}

/* ==========================================================================
   10. CURSEUR PERSONNALISÉ
   --------------------------------------------------------------------------
   Le thème définit .custom-cursor dans style.css (carré sombre, flou en
   arrière-plan, icône en ::before). On ajoute ici :
     - le positionnement par transform plutôt que left/top — mc.motion.js
       n'écrit plus qu'une seule propriété composite, sans recalcul de mise
       en page à chaque image
     - le centrage sur le pointeur, qui manquait : le curseur du thème posait
       son coin supérieur gauche sur la souris
     - l'apparition par changement d'échelle
     - le type "view" pour les vignettes : rond, flèche vers la droite, la
       même que celle des vignettes elles-mêmes
   ========================================================================== */
:root {
	--mc-cur-dur:   0.25s;
	--mc-cur-repos: 0.5;    /* échelle au repos, avant apparition */
}

.custom-cursor {
	left: 0;
	top: 0;
	scale: var( --mc-cur-repos );
	transition:
		opacity var( --mc-cur-dur ) ease,
		scale   var( --mc-cur-dur ) cubic-bezier( 0.22, 1, 0.36, 1 );
}

.custom-cursor.mc-cur-actif {
	scale: 1;
}

.custom-cursor.type-view {
	border-radius: 50%;
}

.custom-cursor.type-view::before {
	font-family: "Font Awesome 5 Pro", sans-serif !important;
	content: "\f178";        /* flèche longue vers la droite */
	display: inline-block;
	font-weight: 300;
}

@media ( prefers-reduced-motion: reduce ) {
	.custom-cursor { transition: opacity var( --mc-cur-dur ) ease; scale: 1; }
}
