/* ==========================================================================
   BORDELUCHE — OBJETS ANIMÉS
   Couche 2 du socle Motion. À charger APRÈS style.css et motion.css.

   Les tokens de motion.css sont utilisés avec un fallback systématique :
   ce fichier reste autonome si motion.css disparaît un jour.

   Règle qui gouverne tout le fichier : aucun état par défaut ne masque de
   contenu. Les effets sont déclenchés par l'ajout d'une classe (.visible,
   .is-open, .m-marquee, .m-wobble) ou par une animation en `both`. Si le JS
   ne tourne pas, la page reste celle d'aujourd'hui.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. COMPTEURS
   Le JS enveloppe le nœud texte numérique dans <span class="m-count">.
   Chiffres tabulaires : sans ça, en font display, la largeur sautille à
   chaque chiffre et la carte tremble pendant le comptage.
   -------------------------------------------------------------------------- */
.m-count {
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum";
}

/* --------------------------------------------------------------------------
   2. TIMELINE DU PARCOURS PROPRIÉTAIRE
   Le connecteur vertical existe déjà dans style.css
   (.processus-step:not(.is-last) .processus-step-left::after).
   On ne le recrée pas — on lui donne une origine et on l'anime.
   -------------------------------------------------------------------------- */
.processus-step:not(.is-last) .processus-step-left::after {
	transform-origin: top center;
}

/* .reveal reçoit .visible via main.js ; .m-visible via motion.js. */
.processus-step.visible:not(.is-last) .processus-step-left::after,
.processus-step.m-visible:not(.is-last) .processus-step-left::after {
	animation: m-draw-line 720ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1))
		140ms both;
}

@keyframes m-draw-line {
	from {
		transform: scaleY(0);
	}
	to {
		transform: scaleY(1);
	}
}

.processus-step.visible .processus-step-num,
.processus-step.m-visible .processus-step-num {
	animation: m-num-pop 520ms var(--ease-overshoot, cubic-bezier(0.34, 1.56, 0.64, 1))
		both;
}

@keyframes m-num-pop {
	from {
		transform: scale(0.82);
	}
	to {
		transform: scale(1);
	}
}

/* --------------------------------------------------------------------------
   3. CARROUSEL INSPIRATIONS
   .deco-track est un scroll natif avec scroll-snap-type: x mandatory et
   deux boutons pilotés par main.js. Le snap ré-aimante la photo à chaque
   frame et se battrait contre un défilement continu : on le désactive
   UNIQUEMENT tant que .m-marquee est posée. Retirer la classe restaure le
   comportement d'origine à l'identique.
   -------------------------------------------------------------------------- */
.deco-track.m-marquee {
	scroll-snap-type: none;
	scrollbar-width: none;
}

.deco-track.m-marquee::-webkit-scrollbar {
	display: none;
}

.deco-photo[data-m-clone] {
	pointer-events: none;
}

.deco-photo img {
	transition: transform 620ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.deco-photo:hover img {
	transform: scale(1.045);
}

/* --------------------------------------------------------------------------
   4. CARTES « LA DIFFÉRENCE »
   Un survol existe déjà : .diff-card:hover::before { opacity: 1 }.
   La transition posée ici est sur .diff-card, pas sur ::before : l'effet
   d'origine est conservé intact, on l'enrichit.
   -------------------------------------------------------------------------- */
.diff-card {
	transition: transform var(--dur-base, 380ms)
			var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1)),
		box-shadow var(--dur-base, 380ms) ease;
}

.diff-card:hover {
	transform: translateY(-4px);
	box-shadow: 0 18px 44px rgba(66, 41, 40, 0.1);
}

.diff-card-num {
	transition: letter-spacing var(--dur-base, 380ms) ease,
		color var(--dur-base, 380ms) ease;
}

.diff-card:hover .diff-card-num {
	letter-spacing: 0.22em;
	color: var(--bordeaux, #422928);
}

.diff-card-icon {
	transition: transform var(--dur-base, 380ms)
		var(--ease-overshoot, cubic-bezier(0.34, 1.56, 0.64, 1));
}

.diff-card:hover .diff-card-icon {
	transform: translateY(-3px) rotate(-4deg);
}

/* --------------------------------------------------------------------------
   5. FAQ — CORRECTION DE L'ACCORDÉON
   style.css anime max-height vers 600px fixes : les réponses courtes
   claquent (la transition parcourt 600px pour 80px de contenu) et les
   longues sont tronquées. grid-template-rows interpole la hauteur réelle.
   -------------------------------------------------------------------------- */
.faq-answer {
	display: block;
	height: 0;
	max-height: none;
	overflow: hidden;
	transition: height 380ms
		var(--ease-in-out-soft, cubic-bezier(0.65, 0, 0.35, 1));
}

/* Repli sans JS : ouverture instantanée à la hauteur réelle. Jamais de
   contenu inaccessible. Le JS, quand il tourne, pose une hauteur en pixels
   en style inline, qui prend le dessus sur cette règle. */
.faq-item.is-open .faq-answer {
	height: auto;
	max-height: none;
}

/* opacity et transform tournent sur le compositeur : c'est ce mouvement-là
   qui porte l'animation, et il ne peut pas saccader. */
.faq-answer-inner {
	opacity: 0;
	transform: translateY(-6px);
	transition: opacity 240ms ease,
		transform 240ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.faq-icon {
	transition: transform 320ms
		var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.faq-item.is-open .faq-answer-inner {
	opacity: 1;
	transform: none;
	transition-delay: 80ms;
}

/* ==========================================================================
   COUCHE 3 — SURVOLS
   ========================================================================== */

/* --------------------------------------------------------------------------
   6. TAG DU HERO — rotation avec retour à la position initiale

   Deux contraintes réelles, vérifiées dans style.css :

   a) .hero-tag porte déjà `opacity: 0; animation: fadeSlideUp .7s .15s
      forwards`. Un `:hover { animation }` remplacerait cette déclaration ;
      `forwards` étant la seule chose qui maintient opacity: 1, le tag
      DISPARAÎTRAIT au survol, puis rejouerait son entrée à chaque sortie de
      souris. La classe .m-tag-ready, posée par le JS une fois l'entrée
      terminée, neutralise `animation` et fige opacity: 1 — le survol ne peut
      plus rien casser.

   b) Le retour à la position initiale ne peut pas venir d'une transition :
      une transition ne revient qu'à la sortie du curseur. C'est donc une
      animation en une passe, retirée à animationend pour pouvoir être
      rejouée au survol suivant.
   -------------------------------------------------------------------------- */
.hero-tag {
	transform-origin: center center;
}

.hero-tag.m-tag-ready {
	animation: none;
	opacity: 1;
}

.hero-tag.m-tag-ready.m-wobble {
	animation: m-tag-wobble 620ms
		var(--ease-overshoot, cubic-bezier(0.34, 1.56, 0.64, 1)) both;
}

@keyframes m-tag-wobble {
	0% {
		transform: rotate(0deg) scale(1);
	}
	32% {
		transform: rotate(-2.6deg) scale(1.022);
	}
	66% {
		transform: rotate(1.1deg) scale(1.006);
	}
	100% {
		transform: rotate(0deg) scale(1);
	}
}

/* --------------------------------------------------------------------------
   7. FLÈCHES DES CTA
   .nav-cta est volontairement absent : `.nav-cta .arrow span` déclare déjà
   `transition: transform .25s ease` et son survol est géré dans style.css.
   Y toucher reviendrait à doubler un effet existant.
   -------------------------------------------------------------------------- */
.footer-cta-arrow,
.btn-primary-arrow svg {
	transition: transform 260ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.footer-cta:hover .footer-cta-arrow,
.btn-primary-section:hover .btn-primary-arrow svg {
	transform: translateX(3px);
}

/* --------------------------------------------------------------------------
   8. PRESTATIONS INCLUSES
   Un filet or apparaît à gauche. Fait en `box-shadow: inset` et non en
   ::before : impossible d'entrer en conflit avec un pseudo-élément
   existant. Le background de survol de style.css est conservé.
   -------------------------------------------------------------------------- */
.offre-prestation {
	transition: box-shadow 320ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1)),
		padding-left 320ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.offre-prestation:hover {
	box-shadow: inset 2px 0 0 0 var(--gold, #e8c97a);
	padding-left: 10px;
}

.offre-prestation-check {
	transition: transform 320ms
		var(--ease-overshoot, cubic-bezier(0.34, 1.56, 0.64, 1));
}

.offre-prestation:hover .offre-prestation-check {
	transform: scale(1.12);
}

/* --------------------------------------------------------------------------
   9. LIENS DE NAVIGATION — RETIRÉ
   Un soulignement au survol existe déjà dans style.css. Celui ajouté ici
   (background-size sur un linear-gradient) ne remplaçait pas l'existant :
   il s'y ajoutait. Résultat, deux traits.
   À ne pas réintroduire : l'effet natif suffit.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   10. CARTES LOGEMENTS ET BLOG
   overflow: hidden est posé sur la carte elle-même plutôt que sur le
   conteneur d'image : ça évite de dépendre du nom de ce conteneur, que la
   recherche de code n'a pas permis d'identifier côté blog.
   -------------------------------------------------------------------------- */
.prop-card,
.blog-card {
	overflow: hidden;
	transition: transform var(--dur-base, 380ms)
			var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1)),
		box-shadow var(--dur-base, 380ms) ease;
}

.prop-card:hover,
.blog-card:hover {
	transform: translateY(-5px);
	box-shadow: 0 20px 48px rgba(66, 41, 40, 0.13);
}

.prop-card img,
.blog-card img {
	transition: transform 760ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.prop-card:hover img,
.blog-card:hover img {
	transform: scale(1.055);
}

/* --------------------------------------------------------------------------
   11. MOUVEMENT RÉDUIT
   Les compteurs, le marquee et la rotation du tag sont neutralisés côté JS.
   Ici on coupe transitions et animations, sans jamais toucher à la
   visibilité ni à la lisibilité.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	.processus-step.visible:not(.is-last) .processus-step-left::after,
	.processus-step.m-visible:not(.is-last) .processus-step-left::after,
	.processus-step.visible .processus-step-num,
	.processus-step.m-visible .processus-step-num,
	.hero-tag.m-tag-ready.m-wobble {
		animation: none;
	}

	.deco-photo img,
	.diff-card,
	.diff-card-num,
	.diff-card-icon,
	.faq-answer,
	.faq-icon,
	.footer-cta-arrow,
	.btn-primary-arrow svg,
	.offre-prestation,
	.offre-prestation-check,
	.prop-card,
	.blog-card,
	.prop-card img,
	.blog-card img {
		transition-duration: 0.01ms;
	}

	.deco-photo:hover img,
	.diff-card:hover,
	.diff-card:hover .diff-card-icon,
	.footer-cta:hover .footer-cta-arrow,
	.btn-primary-section:hover .btn-primary-arrow svg,
	.offre-prestation:hover .offre-prestation-check,
	.prop-card:hover,
	.blog-card:hover,
	.prop-card:hover img,
	.blog-card:hover img {
		transform: none;
	}
}

/* --------------------------------------------------------------------------
   11 bis. FAQ — restauration
   Règle perdue lors du remplacement de la section 5. Replacée ici : même
   spécificité, déclarée plus bas, donc elle s'applique sans ambiguïté.
   -------------------------------------------------------------------------- */
.faq-item.is-open .faq-icon {
	transform: rotate(45deg);
}

/* --------------------------------------------------------------------------
   12. BADGES OTA
   Réutilise m-tag-wobble, déjà défini plus haut. Pas de JS nécessaire :
   .prop-card-platform ne déclare aucune `animation` dans style.css, donc
   rien à préserver — contrairement au tag du hero.
   Le sélecteur [href] ne cible que les badges réellement cliquables : le
   badge de repli reste un libellé inerte.
   -------------------------------------------------------------------------- */
.prop-card-platform.m-ota {
	transform-origin: center center;
}

.prop-card-platform.m-ota[href] {
	cursor: pointer;
	transition: box-shadow 260ms ease;
}

.prop-card-platform.m-ota[href]:hover,
.prop-card-platform.m-ota[href]:focus-visible {
	animation: m-tag-wobble 620ms
		var(--ease-overshoot, cubic-bezier(0.34, 1.56, 0.64, 1)) both;
	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
}

@media (prefers-reduced-motion: reduce) {
	.prop-card-platform.m-ota[href]:hover,
	.prop-card-platform.m-ota[href]:focus-visible {
		animation: none;
	}
}

/* --------------------------------------------------------------------------
   13. PAGE /logements/ — HUB DES LOGEMENTS

   a) Icône de lien externe des boutons Airbnb / Booking. Départ de 2 px en
      diagonale, dans le sens que dessine déjà la flèche de l'icône. La
      variante primaire (« Voir l'étude de cas ») est déjà animée dans la
      page : on ne touche qu'à la secondaire, restée inerte jusqu'ici.

   b) Cascade d'apparition des cartes. L'état masqué est entièrement
      conditionné à .js-reveal, que motion-objects.js ne pose qu'après avoir
      vérifié IntersectionObserver et prefers-reduced-motion. Sans JS,
      aucune carte n'est cachée.

      C'est une TRANSITION et non une animation : la page réordonne ses
      cartes avec appendChild au tri, ce qui peut relancer une animation
      CSS mais laisse une transition dans son état final.

      .reveal-done rend la main à la liste de transitions de la page une
      fois l'entrée terminée. Sans elle, le soulèvement au survol
      hériterait des 520 ms de l'entrée et deviendrait mou.
   -------------------------------------------------------------------------- */
.lg-card-cta--secondary svg {
	transition: transform 220ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.lg-card-cta--secondary:hover svg {
	transform: translate(2px, -2px);
}

.lg-view.js-reveal .lg-card {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity 520ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1)),
		transform 520ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.lg-view.js-reveal .lg-card.is-in {
	opacity: 1;
	transform: none;
}

.lg-view.js-reveal .lg-card.reveal-done {
	transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
}

@media (prefers-reduced-motion: reduce) {
	.lg-card-cta--secondary svg {
		transition-duration: 0.01ms;
	}

	.lg-card-cta--secondary:hover svg {
		transform: none;
	}
}

/* --------------------------------------------------------------------------
   14. PAGE /partenaires/ — PROGRAMME PARTENAIRES

   Deux effets annoncés au départ ne sont PAS ici, et c'est délibéré :

   - Les cascades d'apparition existent déjà. main.js observe .reveal-up et
     pose .visible ; chaque bloc de la page porte son propre --delay en
     style inline. Rien à ajouter, tout à casser.
   - La « timeline du parcours qui se dessine » n'a pas lieu d'être :
     .part-steps est une grille de 2 colonnes (1 seule sous 960 px), pas une
     colonne verticale. Aucun trait continu ne peut la traverser.

   SPÉCIFICITÉ — chaque sélecteur est préfixé par sa section. Les styles de
   page d'Astro sont scopés par un attribut, ce qui porte une règle comme
   `.part-step-num` à (0,2,0). Un `.part-step:hover .part-step-num` global
   vaudrait (0,2,0) lui aussi : égalité, donc l'ordre de chargement des
   feuilles trancherait — et cet ordre n'est pas garanti. Le préfixe monte à
   (0,3,0) et supprime la question.
   -------------------------------------------------------------------------- */

/* 14.a — HALO LENT DU HERO
   Le fond porte déjà trois radial-gradient déclarés dans la page. On n'y
   touche pas : le halo vit dans un ::after dédié, que la page ne déclare
   nulle part. Il dérive et respire sur 26 s, sous l'overlay et sous le
   contenu (z-index: 1), donc jamais au-dessus du texte.
   inset: -20% évite qu'un bord du dégradé n'entre dans le cadre pendant le
   déplacement ; .part-hero est en overflow: hidden, rien ne déborde. */
.part-hero .part-hero-bg::after {
	content: "";
	position: absolute;
	inset: -20%;
	pointer-events: none;
	background: radial-gradient(
			ellipse at 30% 40%,
			rgba(232, 201, 122, 0.1) 0%,
			transparent 55%
		),
		radial-gradient(ellipse at 70% 65%, rgba(111, 127, 117, 0.16) 0%, transparent 50%);
	animation: m-part-halo 26s ease-in-out infinite alternate;
	will-change: transform;
}

@keyframes m-part-halo {
	from {
		transform: translate3d(-2%, -1%, 0) scale(1);
	}
	to {
		transform: translate3d(2%, 2%, 0) scale(1.08);
	}
}

/* 14.b — CHIFFRES 01 → 04 DU PARCOURS
   Le survol de la case existe déjà (le fond s'éclaircit). On lui ajoute le
   seul élément qui ne bougeait pas : le grand chiffre fantôme, posé à 8 %
   d'opacité. Il remonte de 3 px et passe à l'or. C'est la seule couleur de
   marque disponible sur ce fond bordeaux. */
.part-process .part-step-num {
	transition: color 320ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1)),
		transform 320ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.part-process .part-step:hover .part-step-num {
	color: rgba(232, 201, 122, 0.4);
	transform: translateY(-3px);
}

/* 14.c — ICÔNES DES CARTES
   Les trois familles de cartes se soulèvent déjà au survol, mais leur icône
   reste inerte. Elle prend maintenant un léger décalage d'échelle et de
   rotation, sur le même ressort que les icônes de « La Différence » — c'est
   le même geste, pour rester cohérent d'une page à l'autre.
   Aucune de ces icônes ne déclare `transform` dans la page : rien à
   écraser. */
.part-gains .part-gain-icon,
.part-garanties .part-garantie-icon,
.part-profils .part-profil-icon {
	transition: transform 340ms
		var(--ease-overshoot, cubic-bezier(0.34, 1.56, 0.64, 1));
}

.part-gains .part-gain-card:hover .part-gain-icon,
.part-garanties .part-garantie:hover .part-garantie-icon,
.part-profils .part-profil-card:hover .part-profil-icon {
	transform: scale(1.09) rotate(-4deg);
}

/* 14.d — LIEN « VOIR LE SIMULATEUR »
   Le trait sous le lien existe déjà et change de couleur. On ajoute
   uniquement un décalage horizontal, qui suit la flèche du libellé. */
.part-gains .part-gain-link {
	transition: color 200ms ease, border-color 200ms ease,
		transform 240ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.part-gains .part-gain-link:hover {
	transform: translateX(3px);
}

/* 14.e — MOUVEMENT RÉDUIT */
@media (prefers-reduced-motion: reduce) {
	.part-hero .part-hero-bg::after {
		animation: none;
	}

	.part-process .part-step-num,
	.part-gains .part-gain-icon,
	.part-garanties .part-garantie-icon,
	.part-profils .part-profil-icon,
	.part-gains .part-gain-link {
		transition-duration: 0.01ms;
	}

	.part-process .part-step:hover .part-step-num,
	.part-gains .part-gain-card:hover .part-gain-icon,
	.part-garanties .part-garantie:hover .part-garantie-icon,
	.part-profils .part-profil-card:hover .part-profil-icon,
	.part-gains .part-gain-link:hover {
		transform: none;
	}
}

/* --------------------------------------------------------------------------
   15. PAGE /logements/[slug] — FICHE D'UN LOGEMENT

   Ce qui n'est PAS ici, et pourquoi :

   - Les cascades d'apparition existent déjà : .lgt-infos-left,
     .lgt-infos-right, .lgt-case-header, les quatre .lgt-step et
     .lgt-cta-inner portent toutes .reveal-up avec leur propre --delay, et
     main.js les observe. Rien à ajouter.
   - Le carrousel de photos est déjà animé et entièrement autonome
     (transition de 0,35 s, défilement auto de 4,5 s, pause au survol).
     Y toucher depuis ici ne ferait qu'entrer en conflit.
   - La vidéo du hero est déjà coupée en mouvement réduit par la page.

   Les compteurs de cette page (.lgt-stat-value, .lgt-results-stat-value)
   sont câblés dans motion-objects.js, pas ici. Ils héritent de .m-count
   déclaré en section 1.

   SPÉCIFICITÉ — la page est en <style> scopé Astro, donc à (0,2,0). Chaque
   sélecteur ci-dessous est préfixé par sa section pour monter à (0,3,0).
   -------------------------------------------------------------------------- */

/* 15.a — FLÈCHE DU CTA FINAL
   Le bouton se soulève déjà de 3 px et la pastille .lgt-cta-arrow change de
   fond, mais la flèche elle-même ne bougeait pas. On ne touche qu'au svg :
   le fond de la pastille reste piloté par la page. */
.lgt-cta .lgt-cta-arrow svg {
	transition: transform 260ms var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.lgt-cta .lgt-cta-btn:hover .lgt-cta-arrow svg {
	transform: translateX(3px);
}

/* 15.b — CHIFFRES 01 → 04 DE L'ÉTUDE DE CAS
   Aucune règle de survol n'existait sur ces chiffres. Même geste que sur
   /partenaires/, à une différence près et elle est délibérée : la COULEUR
   n'est pas touchée. L'étape 04 (.lgt-step-results) porte sa propre teinte
   verte ; une couleur globale la remplacerait au survol. Seule la
   transformation joue, elle est neutre vis-à-vis de la teinte. */
.lgt-case .lgt-step-num {
	display: inline-block;
	transition: transform 320ms
		var(--ease-out-soft, cubic-bezier(0.16, 1, 0.3, 1));
}

.lgt-case .lgt-step:hover .lgt-step-num {
	transform: translateY(-3px) scale(1.06);
}

/* 15.c — MOUVEMENT RÉDUIT */
@media (prefers-reduced-motion: reduce) {
	.lgt-cta .lgt-cta-arrow svg,
	.lgt-case .lgt-step-num {
		transition-duration: 0.01ms;
	}

	.lgt-cta .lgt-cta-btn:hover .lgt-cta-arrow svg,
	.lgt-case .lgt-step:hover .lgt-step-num {
		transform: none;
	}
}
