/* =============================================================================
   com'ing — animations niveau B+ (motion-design.md, animations-tech.md §8)
   Règles : uniquement transform / opacity / clip-path ; états cachés SEULEMENT sous html.has-motion
   (classe posée par un script inline si prefers-reduced-motion n'est pas actif et si le niveau global != Aucune) ;
   jamais d'opacity:0 sur le H1 (LCP). Non chargé dans l'éditeur.
   ============================================================================= */

/* ---------- Apparitions au défilement ---------- */
.has-motion .coming-reveal--reveal,
.has-motion .coming-reveal--line,
.has-motion .coming-reveal--count,
.has-motion .coming-stagger-item {
	opacity: 0;
	transform: translateY(var(--wp--custom--motion--distance));
	transition: opacity var(--wp--custom--motion--d-reveal) var(--wp--custom--motion--ease-out), transform var(--wp--custom--motion--d-reveal) var(--wp--custom--motion--ease-out);
	transition-delay: calc(var(--i, 0) * var(--wp--custom--motion--stagger));
}
.has-motion .coming-reveal--reveal.is-in,
.has-motion .coming-reveal--line.is-in,
.has-motion .coming-reveal--count.is-in,
.has-motion .coming-stagger-item.is-in { opacity: 1; transform: none; }
/* NB : `translate`/`rotate` (décalages statiques des cartes) et `transform` (apparition) se composent : ne pas les écraser ici (B4). */
/* volet sur image (T8), respecte l'arrondi */
.has-motion .coming-reveal--mask { clip-path: inset(100% 0 0 0 round var(--wp--custom--radius--media)); transition: clip-path 1000ms var(--wp--custom--motion--ease-io); transition-delay: calc(var(--i, 0) * var(--wp--custom--motion--stagger)); }
.has-motion .coming-reveal--mask.is-in { clip-path: inset(0 0 0 0 round var(--wp--custom--radius--media)); }
/* filets qui se tracent (T7) */
.has-motion .coming-reveal--line { opacity: 1; transform: none; }
.has-motion .coming-reveal--line::before, .has-motion .coming-reveal--line .coming-svc-row::before { transform: scaleX(0); transform-origin: left; transition: transform 900ms var(--wp--custom--motion--ease-out); transition-delay: calc(var(--i, 0) * var(--wp--custom--motion--stagger)); }
.has-motion .coming-reveal--line.is-in::before, .has-motion .coming-reveal--line.is-in .coming-svc-row::before, .has-motion .coming-stagger-item.is-in.coming-svc-row::before { transform: scaleX(1); }
.has-motion .coming-svc-list.coming-reveal--stagger .coming-svc-row { transform: none; }
.has-motion .coming-svc-row.coming-stagger-item::before { transform: scaleX(0); transition: transform 900ms var(--wp--custom--motion--ease-out); transition-delay: calc(var(--i, 0) * var(--wp--custom--motion--stagger)); }
.has-motion .coming-svc-row.coming-stagger-item.is-in::before { transform: scaleX(1); }

/* ---------- Hero : révélation masquée ligne par ligne (démarre au premier rendu, sans JS) ---------- */
@keyframes comingLineUp { from { transform: translateY(108%); } to { transform: none; } }
@keyframes comingFadeUp { from { opacity: 0; transform: translateY(var(--wp--custom--motion--distance)); } to { opacity: 1; transform: none; } }
@keyframes comingSlideUp { from { transform: translateY(0.4em); } to { transform: none; } }
@keyframes comingSettle { from { opacity: 0; transform: translate(14%, 10%); } to { opacity: 1; transform: none; } }
.motion-full .coming-line > span { animation: comingLineUp var(--wp--custom--motion--d-hero) var(--wp--custom--motion--ease-out) both; animation-delay: calc(var(--i, 0) * 120ms + 80ms); }
/* repli si l'édition a aplati les <span> : léger glissement SANS opacité (le H1 est toujours peint, LCP) */
.motion-full h1.coming-hero__title:not(:has(.coming-line)) { animation: comingSlideUp var(--wp--custom--motion--d-reveal) var(--wp--custom--motion--ease-out) both; }
.motion-full .coming-hero-after { animation: comingFadeUp var(--wp--custom--motion--d-reveal) var(--wp--custom--motion--ease-out) both; animation-delay: 560ms; }
/* 1re photo du collage = image LCP (coming-lcp) : AUCUNE animation d'apparition, peinte au premier rendu (B3). */
.motion-full .coming-hero__collage > .coming-media:nth-child(2) { animation: comingSettle 1000ms var(--wp--custom--motion--ease-out) both; animation-delay: 640ms; }
.motion-full .coming-pastille { animation: comingFadeUp 700ms var(--wp--custom--motion--ease-out) both; animation-delay: 900ms; }
/* AC3 : mot qui change. Le mot final est le vrai texte (.coming-swap__final) ; les mots alternatifs sont en data-a1/data-a2, affichés en
   ::before/::after dans la même cellule de grille (largeur réservée = pas de décalage de mise en page). Une seule fois, ~1,9 s après le début.
   Sans animation (reduced-motion, Subtil, Aucune, interrupteur coupé) : seul le mot final existe, rien ne change. */
.motion-full .coming-swap { display: inline-grid; justify-items: start; vertical-align: baseline; }
.motion-full .coming-swap > *, .motion-full .coming-swap::before, .motion-full .coming-swap::after { grid-area: 1 / 1; }
.motion-full .coming-swap::before { content: attr(data-a1); content: attr(data-a1) / ""; visibility: hidden; }
.motion-full .coming-swap--2::after { content: attr(data-a2); content: attr(data-a2) / ""; visibility: hidden; }
@keyframes comingWordA { 0%, 99.9% { visibility: visible; } 100% { visibility: hidden; } }
@keyframes comingWordA2 { 0%, 49.9% { visibility: visible; } 50%, 100% { visibility: hidden; } }
@keyframes comingWordB { 0%, 49.9% { visibility: hidden; } 50%, 99.9% { visibility: visible; } 100% { visibility: hidden; } }
@keyframes comingWordF { 0%, 99.9% { visibility: hidden; } 100% { visibility: visible; } }
.motion-full .coming-swap--1::before { animation: comingWordA 800ms steps(1, end) 320ms both; }
.motion-full .coming-swap--1 .coming-swap__final { animation: comingWordF 800ms steps(1, end) 320ms both; }
.motion-full .coming-swap--2::before { animation: comingWordA2 1600ms steps(1, end) 320ms both; }
.motion-full .coming-swap--2::after { animation: comingWordB 1600ms steps(1, end) 320ms both; }
.motion-full .coming-swap--2 .coming-swap__final { animation: comingWordF 1600ms steps(1, end) 320ms both; }
/* CTA : lignes */
.motion-full .coming-cta__title.coming-reveal--reveal { opacity: 1; transform: none; }
.has-motion .coming-cta__title .coming-line > span { transform: translateY(108%); transition: transform var(--wp--custom--motion--d-hero) var(--wp--custom--motion--ease-out); transition-delay: calc(var(--i, 0) * 120ms); animation: none; }
.has-motion .coming-cta__title.is-in .coming-line > span { transform: none; }
/* titres de page secondaires (À propos, Services) : lignes en entrée, comme le hero */
.motion-full .coming-page-title .coming-line > span { animation: comingLineUp var(--wp--custom--motion--d-hero) var(--wp--custom--motion--ease-out) both; animation-delay: calc(var(--i, 0) * 120ms + 80ms); }

/* ---------- Défilé de logos ---------- */
@keyframes comingMarquee { to { transform: translateX(-50%); } }
.coming-marquee.is-scrolling .coming-marquee__rail { animation: comingMarquee 38s linear infinite; }
.coming-marquee.is-paused .coming-marquee__rail, .coming-marquee:hover .coming-marquee__rail, .coming-marquee:focus-within .coming-marquee__rail { animation-play-state: paused; }

/* ---------- Header qui se compacte (CSS pur, sans écouteur ; sans support : reste à l'état normal) ---------- */
@supports (animation-timeline: scroll()) {
	@keyframes comingHeaderCompact { to { background-color: rgba(250, 247, 239, 0.96); box-shadow: 0 1px 0 rgba(20, 19, 16, 0.12); } }
	@keyframes comingLogoShrink { to { transform: scale(0.84); } }
	.motion-full .coming-site-header, .motion-subtle .coming-site-header { animation: comingHeaderCompact linear both; animation-timeline: scroll(root); animation-range: 0 80px; }
	.motion-full .coming-site-header .wp-block-site-logo, .motion-subtle .coming-site-header .wp-block-site-logo { transform-origin: left center; animation: comingLogoShrink linear both; animation-timeline: scroll(root); animation-range: 0 80px; }
}

/* ---------- Menu mobile : volet + liens décalés (ouverture uniquement, focus trap natif intact) ---------- */
@keyframes comingPanelDown { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
.motion-full .wp-block-navigation__responsive-container.is-menu-open { animation: comingPanelDown var(--wp--custom--motion--d-base) var(--wp--custom--motion--ease-io) both; }
.motion-full .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item { animation: comingFadeUp 500ms var(--wp--custom--motion--ease-out) both; animation-delay: 200ms; }

/* ---------- Niveau « Subtil » : pas de hero animé, pas de défilé (géré aussi côté JS) ---------- */
.motion-subtle .coming-line > span { animation: none; }

/* ---------- Transitions de filtre portfolio ----------
   `@view-transition { navigation: auto }` volontairement RETIRÉ du site entier (approuvé par Theo seulement pour les filtres
   Réalisations). À réintroduire avec le gabarit Réalisations, dans une feuille chargée sur ces seules pages. */
::view-transition-group(*) { animation-duration: 480ms; animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); }

/* ---------- Fiche Réalisation « La planche » (fiche-realisation-creative.md §5) ----------
   Hero : texte peint dès la 1re image (glissement de 24px, jamais d'opacité) ; le visuel (LCP) est déjà peint, un volet beige se retire.
   Planche, livrables, cartes : montée liée au défilement (animation-timeline), jamais d'état caché de départ. */
@keyframes comingVolet { to { transform: translateY(-101%); } }
@keyframes comingRise { from { transform: translateY(var(--wp--custom--motion--distance)); } to { transform: none; } }
.motion-full .coming-fiche-hero__text > * { animation: comingRise var(--wp--custom--motion--d-reveal) var(--wp--custom--motion--ease-out) both; }
.motion-full .coming-fiche-hero__text > :nth-child(3) { animation-delay: 100ms; }
.motion-full .coming-fiche-hero__text > :nth-child(4) { animation-delay: 200ms; }
.motion-full .coming-fiche-hero__text > :nth-child(n+5) { animation-delay: 300ms; }
.motion-full .coming-fiche-hero__img::after { content: ""; position: absolute; inset: 0; z-index: 1; background: var(--wp--preset--color--beige-100); pointer-events: none; animation: comingVolet var(--wp--custom--motion--d-reveal) var(--wp--custom--motion--ease-io) 250ms forwards; }
@supports (animation-timeline: view()) {
	.motion-full :is(.coming-planche .wp-block-image, .coming-planche .is-style-coming-quote-card, .is-style-coming-deliverables > li, .coming-rcard) { animation: comingRise linear both; animation-timeline: view(); animation-range: entry 0% entry 45%; }
}

/* ---------- Sécurité : préférence système ---------- */
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after { animation: none !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }
	.coming-marquee { mask-image: none; }
}

/* ---------- Pages Service (services.css) : états « caché avant apparition » et volet du hero ---------- */
/* Rangées de l'index et réseaux de la bande : le filet se trace en même temps que la rangée apparaît (fondu + montée en décalé, déjà fait par .coming-stagger-item) */
.has-motion .svc-idx__row.coming-stagger-item::after, .has-motion .svc-stair li.coming-stagger-item::after, .has-motion .svc-nets li.coming-stagger-item::before { transform: scaleX(0); transition-delay: calc(var(--i, 0) * var(--wp--custom--motion--stagger)); }
.has-motion .svc-idx__row.coming-stagger-item.is-in::after, .has-motion .svc-stair li.coming-stagger-item.is-in::after, .has-motion .svc-nets li.coming-stagger-item.is-in::before { transform: scaleX(1); }
/* Hero : la photo (image LCP, peinte et visible dans le HTML) est dévoilée par un calque qui se retire : animation CSS pure au premier rendu, aucun JavaScript */
.motion-full .svc-hero .svc-photo::after { content: ""; position: absolute; inset: 0; z-index: 1; background: var(--wp--preset--color--beige-050); pointer-events: none; animation: comingVolet var(--wp--custom--motion--d-reveal) var(--wp--custom--motion--ease-io) 250ms forwards; }

/* Pages Service v3, compositions : filets qui se tracent à l'apparition des rangées */
.has-motion .svc-cat__row.coming-stagger-item::after, .has-motion .svc-qs li.coming-stagger-item::after, .has-motion .svc-ledger li.coming-stagger-item::after, .has-motion .svc-st li.coming-stagger-item::after, .has-motion .svc-sect__list li.coming-stagger-item::after, .has-motion .svc-som li.coming-stagger-item::after { transform: scaleX(0); transition-delay: calc(var(--i, 0) * var(--wp--custom--motion--stagger)); }
.has-motion .svc-cat__row.coming-stagger-item.is-in::after, .has-motion .svc-qs li.coming-stagger-item.is-in::after, .has-motion .svc-ledger li.coming-stagger-item.is-in::after, .has-motion .svc-st li.coming-stagger-item.is-in::after, .has-motion .svc-sect__list li.coming-stagger-item.is-in::after, .has-motion .svc-som li.coming-stagger-item.is-in::after { transform: scaleX(1); }
