/* ============================================================================
   METABOLIQ · MOTION LAYER (staging) — micro-animazioni premium home
   ----------------------------------------------------------------------------
   Layer SEPARATO dal Custom CSS del Customizer (gestito da Elena) e dalla
   card-anim (gauge/count-up, gestita da metaboliq-card-animation.php).
   Enqueued via mu-plugin: metaboliq-motion.php
     -> wp-content/uploads/metaboliq/metaboliq-motion.css  (questo file)
     -> wp-content/uploads/metaboliq/metaboliq-motion.js

   Autore: Dario — Innova Design Studio · giugno 2026

   PRINCIPI
   - Solo transform/opacity (compositor-friendly, niente layout shift/jank).
   - Reveal una-tantum gestito da IntersectionObserver (unobserve dopo trigger).
   - Graceful degradation: il "nascondino" del reveal si attiva SOLO quando il
     JS ha aggiunto html.mb-motion-ready. Se il JS non parte, nulla resta nascosto.
   - prefers-reduced-motion: reduce -> tutto disattivato, stato finale statico.
   - NON ridefinisce stili di layout/colore: tocca solo transition/transform.
   ============================================================================ */

:root{
  /* easing coerente con il brand (stesso usato nel Custom CSS: --mb-ease-out) */
  --mb-mo-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --mb-mo-dur: 0.62s;
  --mb-mo-shift: 20px;   /* translateY iniziale del reveal */
}

/* ============================================================================
   1 · REVEAL ON SCROLL (fade + translateY, stagger sulle griglie)
   ----------------------------------------------------------------------------
   .mb-rv          = candidato al reveal (classe messa dal JS)
   .is-in          = stato finale (classe messa dal JS al trigger IO)
   Lo stato "nascosto" è condizionato a html.mb-motion-ready: se il JS non
   esegue, gli elementi restano nel loro flusso normale e visibili.
   ============================================================================ */
html.mb-motion-ready .mb-rv{
  opacity: 0;
  transform: translate3d(0, var(--mb-mo-shift), 0);
  transition:
    opacity var(--mb-mo-dur) var(--mb-mo-ease),
    transform var(--mb-mo-dur) var(--mb-mo-ease);
  will-change: opacity, transform;
}
html.mb-motion-ready .mb-rv.is-in{
  opacity: 1;
  transform: translate3d(0, 0, 0);
}
/* dopo l'entrata liberiamo will-change (micro-ottimizzazione) */
html.mb-motion-ready .mb-rv.is-done{
  will-change: auto;
}

/* ============================================================================
   2 · HOVER CARD (lift + ombra morbida)
   ----------------------------------------------------------------------------
   Solo le card "informative": problema, diagnostica, team.
   ESCLUSA di proposito la .mb-card della hero (referto vivo, non interattivo).
   Niente cambi di dimensione/box-model -> nessun layout shift.
   ============================================================================ */
.mb-prob-card,
.mb-diag-card,
.mb-team-card{
  transition:
    transform 0.28s var(--mb-mo-ease),
    box-shadow 0.28s var(--mb-mo-ease),
    border-color 0.28s var(--mb-mo-ease);
  will-change: transform;
}
.mb-prob-card:hover,
.mb-diag-card:hover,
.mb-team-card:hover{
  transform: translate3d(0, -6px, 0);
  box-shadow:
    0 2px 4px rgba(40, 89, 67, 0.06),
    0 18px 40px rgba(40, 89, 67, 0.14);
  border-color: rgba(40, 89, 67, 0.18);
}
/* La problema-card nel Custom CSS ha solo border (niente shadow di base):
   in hover diamo comunque un'ombra morbida coerente col resto. */

/* ============================================================================
   3 · CTA — già coperte dal Custom CSS (#mb-cta, #mb-ctaf-btn):
   freccia + lift + shadow + reduced-motion guard sono già lì.
   NIENTE duplicazione qui. (Vedi report a Elena.)
   ============================================================================ */

/* ============================================================================
   4 · PITTOGRAMMA M (#mb-simbolo .mb-simbolo-mono)
   ----------------------------------------------------------------------------
   L'hover desktop è già nel <style> del widget (.mb-simbolo-mono:hover ...).
   Qui aggiungiamo SOLO il trigger al reveal (anche touch): le due figure si
   avvicinano e poi tornano, una volta, quando la sezione entra in viewport.
   La classe .mb-mono-play è messa/rimossa dal JS.
   Non tocchiamo le regole di hover esistenti.
   ============================================================================ */
.mb-simbolo-mono.mb-mono-play .mb-fig-l{ transform: translateX(34px); }
.mb-simbolo-mono.mb-mono-play .mb-fig-r{ transform: translateX(-34px); }
.mb-simbolo-mono.mb-mono-play circle{ fill: var(--mb-celadon, #88BB92); }
/* la transizione sui circle è già definita nel widget (.55s ease-out):
   riusandola, l'andata col .play e il ritorno (JS rimuove la classe) sono fluidi. */

/* ============================================================================
   6 · HERO — float leggero sulla card composizione corporea (#mb-hero-card-wrap)
   ----------------------------------------------------------------------------
   OPZIONALE e a basso movimento. Gated da .mb-float-ok (messa dal JS solo se
   non reduced-motion). Float minimo (3px) e lento (6s) per evitare jank.
   Il float parte DOPO che la card-anim ha finito (il JS aggiunge la classe in
   ritardo), così non interferisce con gauge/count-up.
   ============================================================================ */
@keyframes mbHeroFloat{
  0%   { transform: translate3d(0, 0, 0); }
  50%  { transform: translate3d(0, -3px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}
#mb-hero-card-wrap.mb-float-ok .mb-card{
  animation: mbHeroFloat 6s ease-in-out infinite;
  will-change: transform;
}
/* pausa il float quando si interagisce/hovera la card (cortesia) */
#mb-hero-card-wrap.mb-float-ok .mb-card:hover{
  animation-play-state: paused;
}

/* ============================================================================
   7 · HERO ENTRANCE AL LOAD — WEB ANIMATIONS API (v4)  [marker: mb-enter-v4]
   ----------------------------------------------------------------------------
   RISCRITTURA (Dario · giugno 2026), dopo diagnosi RUNTIME (Elena, DevTools
   sulla pagina live): la vecchia state-machine CSS (.mb-enter "hidden" →
   .is-shown "shown", + gate :not(.is-shown), + pre-paint) NON convergeva: con
   l'opacity custom (#mb-eyebrow .78 / #mb-subhead .86) e i tempi di commit di
   pre-paint→is-shown nello stesso frame, gli elementi restavano INCHIODATI a
   opacity 0 → HERO INVISIBILE. getComputedStyle dava 0 anche con .is-shown.

   NUOVO APPROCCIO — niente più classi hidden/shown in conflitto:
   l'entrata è interamente gestita dalla Web Animations API nel JS
   (setupHeroEntrance): per ogni elemento un el.animate([from,to], opts) con
   fill:'backwards'. Durante il delay l'elemento è a opacity 0 (keyframe from);
   a fine animazione l'effetto si stacca e l'elemento TORNA al suo valore CSS
   NATURALE (Custom CSS: eyebrow .78, subhead .86, h1/claim/cta/card 1) — che
   COINCIDE col keyframe finale → nessun salto.

   PERCHÉ QUI NON C'È PIÙ NESSUNA REGOLA DI STATO:
   lo stato A RIPOSO degli elementi hero deve essere quello naturale del Custom
   CSS = VISIBILE. Qualunque `opacity:0` su questi id (fuori dal pre-paint, che
   viene SEMPRE rimosso) reintrodurrebbe il bug. Perciò il layer 7 non impone
   più opacity/transform/transition agli elementi hero: l'unico "nascondino" è
   il pre-paint anti-FOUC qui sotto (gate html.mb-hero-pre), temporaneo.

   - REQUISITO ASSOLUTO: senza JS / con JS fallito / reduced-motion / a entrata
     finita → hero VISIBILE ai valori finali. Mai opacity 0 persistente.
   - card-anim: il count-up gira sul suo rAF a prescindere; la WAAPI anima il
     WRAPPER #mb-hero-card-wrap (mai .mb-card) → nessun conflitto col float né
     con gli stili inline di card-anim.js dentro .mb-card.
   ============================================================================ */

/* --- PRE-PAINT anti-FOUC (UNICO nascondino, temporaneo) — gate html.mb-hero-pre
   La classe la mette un micro-script SINCRONO nel <head> (vedi .php), PRIMA del
   primo paint, così l'utente non vede l'hero a posizione finale per un frame
   prima che parta la WAAPI. translateY/blur/scale coerenti col linguaggio
   premium dell'entrata (eyebrow rise corto; h1 blur+rise; card scale+rise).
   Il JS rimuove mb-hero-pre SUBITO PRIMA di lanciare le animate(); un fallback
   timeout nel <head> la rimuove se il JS non parte → mai hero invisibile, mai
   FOUC con JS off. reduced-motion: mb-hero-pre NON viene applicato. */
html.mb-hero-pre #mb-eyebrow{
  opacity: 0 !important;
  transform: translate3d(0, 12px, 0);
}
html.mb-hero-pre #mb-h1{
  opacity: 0 !important;
  transform: translate3d(0, 22px, 0);
  filter: blur(8px) !important;
}
html.mb-hero-pre #mb-hero-claim,
html.mb-hero-pre #mb-subhead,
html.mb-hero-pre #mb-cta,
html.mb-hero-pre #mb-cta-presenza{
  opacity: 0 !important;
  transform: translate3d(0, 18px, 0);
}
/* 15/09/2026: descrizioni sotto i due pulsanti "Prenota una visita" */
html.mb-hero-pre #mb-cta-desc-online,
html.mb-hero-pre #mb-cta-desc-presenza{
  opacity: 0 !important;
  transform: translate3d(0, 12px, 0);
}
html.mb-hero-pre #mb-hero-card-wrap{
  opacity: 0 !important;
  transform: translate3d(0, 16px, 0) scale(0.96);
  transform-origin: 50% 60%;
}

/* ============================================================================
   8 · FAQ ACCORDION FLUIDO (#mb-faq-sec, widget .mb-faq)
   ----------------------------------------------------------------------------
   Markup reale: <details class="mb-faq-item"> > <summary> + <div class="mb-faq-a">.
   Icona = .mb-faq-plus (+ via ::before/::after; su [open] ::after→opacity 0 = "−").
   Il <details> nativo apre/chiude in modo istantaneo: rendiamo fluido il pannello
   risposta animando un wrapper di altezza (.mb-faq-a-wrap, iniettato dal JS) via
   grid-template-rows 0fr→1fr + opacity. Il JS gestisce open/close (keep-open per
   l'animazione di chiusura) e aria-expanded. Aggiungiamo anche rotazione lieve
   dell'icona, oltre al morph +/− già presente nel widget.
   Gate: html.mb-faq-js (messo dal JS solo se prende il controllo dei details).
   Se il JS non parte → resta il <details> nativo, perfettamente funzionante.
   ============================================================================ */
/* wrapper di altezza iniettato dal JS attorno a .mb-faq-a */
html.mb-faq-js .mb-faq .mb-faq-a-wrap{
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  will-change: grid-template-rows, opacity;
}
/* la transizione si attiva SOLO dopo .mb-faq-ready (next frame): così l'item
   inizialmente aperto appare già aperto senza animarsi al load (niente motion
   non richiesto). Da lì in poi ogni click apre/chiude in modo fluido. */
html.mb-faq-js .mb-faq.mb-faq-ready .mb-faq-a-wrap{
  transition:
    grid-template-rows var(--mb-mo-dur) var(--mb-mo-ease),
    opacity calc(var(--mb-mo-dur) * 0.8) var(--mb-mo-ease);
}
/* il figlio diretto del grid deve poter collassare a 0 */
html.mb-faq-js .mb-faq .mb-faq-a-wrap > .mb-faq-a{
  min-height: 0;
  overflow: hidden;
}
/* stato aperto: riga a 1fr + opacità piena. .is-open la mette il JS. */
html.mb-faq-js .mb-faq .mb-faq-item.is-open .mb-faq-a-wrap{
  grid-template-rows: 1fr;
  opacity: 1;
}
/* ============================================================================
   9 · FAQ ICONA +/− (versione bulletproof v2)
   ----------------------------------------------------------------------------
   Convenzione:
     • Stato CHIUSO: cerchio crema, "+" arancione (orizzontale + verticale visibili)
     • Stato APERTO: cerchio arancione, "−" bianco (verticale collassa via scaleY)
   Stato aperto è determinato da:
     • [open] HTML attribute SOLO se JS motion non gira (fallback no-JS)
     • .is-open class quando JS motion gira (caso normale: tutti gli item hanno
       [open] sempre per il pannello, lo stato visivo va via .is-open)
   Uso !important su proprietà chiave per battere eventuali regole tema.
   ============================================================================ */

/* === CERCHIO BASE (stato chiuso) === */
.mb-faq-ico,
.mb-faq-plus{
  position:relative !important;
  flex:0 0 auto !important;
  width:26px !important;
  height:26px !important;
  border-radius:50% !important;
  background:var(--mb-cream,#FCEEE3) !important;
  transition:background-color .28s cubic-bezier(.16,1,.3,1) !important;
}

/* === BARRE DEL "+" (chiuso) === */
.mb-faq-ico::before,.mb-faq-ico::after,
.mb-faq-plus::before,.mb-faq-plus::after{
  content:"" !important;
  position:absolute !important;
  top:50% !important;
  left:50% !important;
  background:var(--mb-orange,#F75C03) !important;
  border-radius:2px !important;
  opacity:1 !important;
  transition:transform .32s cubic-bezier(.16,1,.3,1),
             background-color .28s cubic-bezier(.16,1,.3,1),
             opacity .22s ease !important;
}
/* Orizzontale: 12×2 */
.mb-faq-ico::before,.mb-faq-plus::before{
  width:12px !important;
  height:2px !important;
  transform:translate(-50%,-50%) !important;
}
/* Verticale: 2×12 */
.mb-faq-ico::after,.mb-faq-plus::after{
  width:2px !important;
  height:12px !important;
  transform:translate(-50%,-50%) !important;
}

/* === STATO APERTO === */
/* Cerchio diventa arancio */
html:not(.mb-faq-js) .mb-faq-item[open] .mb-faq-ico,
html:not(.mb-faq-js) .mb-faq-item[open] .mb-faq-plus,
html.mb-faq-js .mb-faq-item.is-open .mb-faq-ico,
html.mb-faq-js .mb-faq-item.is-open .mb-faq-plus{
  background:var(--mb-orange,#F75C03) !important;
}
/* Barra orizzontale resta visibile ma diventa bianca */
html:not(.mb-faq-js) .mb-faq-item[open] .mb-faq-ico::before,
html:not(.mb-faq-js) .mb-faq-item[open] .mb-faq-plus::before,
html.mb-faq-js .mb-faq-item.is-open .mb-faq-ico::before,
html.mb-faq-js .mb-faq-item.is-open .mb-faq-plus::before{
  background:var(--mb-white,#fff) !important;
  opacity:1 !important;
}
/* Barra verticale collassa (scaleY 0) e diventa invisibile → resta solo "−" */
html:not(.mb-faq-js) .mb-faq-item[open] .mb-faq-ico::after,
html:not(.mb-faq-js) .mb-faq-item[open] .mb-faq-plus::after,
html.mb-faq-js .mb-faq-item.is-open .mb-faq-ico::after,
html.mb-faq-js .mb-faq-item.is-open .mb-faq-plus::after{
  background:var(--mb-white,#fff) !important;
  transform:translate(-50%,-50%) scaleY(0) !important;
  opacity:0 !important;
}

/* ============================================================================
   REDUCED MOTION — stato finale statico, zero animazioni
   ============================================================================ */
@media (prefers-reduced-motion: reduce){
  html.mb-motion-ready .mb-rv,
  html.mb-motion-ready .mb-rv.is-in{
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    will-change: auto !important;
  }
  .mb-prob-card,
  .mb-diag-card,
  .mb-team-card{
    transition: none !important;
    will-change: auto !important;
  }
  .mb-prob-card:hover,
  .mb-diag-card:hover,
  .mb-team-card:hover{
    transform: none !important;
  }
  .mb-simbolo-mono.mb-mono-play .mb-fig-l,
  .mb-simbolo-mono.mb-mono-play .mb-fig-r{ transform: none !important; }
  .mb-simbolo-mono.mb-mono-play circle{ fill: var(--mb-jungle, #285943) !important; }
  #mb-hero-card-wrap.mb-float-ok .mb-card{ animation: none !important; will-change: auto !important; }

  /* 7 · hero entrance (v4, WAAPI): in reduced-motion il JS NON lancia animate()
     e il micro-script <head> NON aggiunge mb-hero-pre → l'hero è già allo stato
     naturale (Custom CSS: eyebrow .78, subhead .86, resto 1), visibile e fermo.
     Cintura+bretelle: se per qualunque edge mb-hero-pre fosse presente, qui la
     neutralizziamo riportando gli id hero al loro valore visibile.
     NB: non tocchiamo eyebrow/subhead con opacity:1 — lasciamo che restino al
     valore brand del Custom CSS (.78/.86); azzeriamo solo l'eventuale pre-paint
     (transform/filter) e l'opacity:0 del pre-paint su h1/claim/cta/card. */
  html.mb-hero-pre #mb-eyebrow,
  html.mb-hero-pre #mb-h1,
  html.mb-hero-pre #mb-hero-claim,
  html.mb-hero-pre #mb-subhead,
  html.mb-hero-pre #mb-cta,
  html.mb-hero-pre #mb-cta-presenza,
  html.mb-hero-pre #mb-hero-card-wrap{
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    transition: none !important;
    will-change: auto !important;
  }
  /* 15/09/2026: descrizioni sotto i pulsanti, al loro valore naturale .78 */
  html.mb-hero-pre #mb-cta-desc-online,
  html.mb-hero-pre #mb-cta-desc-presenza{
    opacity: .78 !important;
    transform: none !important;
    transition: none !important;
  }

  /* 8 · FAQ: nessuna animazione di altezza; pannello aperto = visibile, chiuso = nascosto.
     (Il JS gestisce comunque open/close; qui togliamo solo la transizione e la rotazione.) */
  html.mb-faq-js .mb-faq .mb-faq-a-wrap{
    transition: none !important;
    will-change: auto !important;
  }
  html.mb-faq-js .mb-faq .mb-faq-item.is-open .mb-faq-plus{
    transform: none !important;
  }
}

/* ============================================================================
   PAGE TRANSITIONS — View Transitions API (cross-document MPA) + CTA :active
   Aggiunto 24 giu 2026 (Dario). Leggero (≤240ms), reduced-motion-safe.
   ============================================================================ */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: no-preference){
  ::view-transition-old(root){ animation: mbVtOut .20s ease both; }
  ::view-transition-new(root){ animation: mbVtIn  .24s ease both; }
  @keyframes mbVtOut{ to  { opacity:0; transform: translateY(-6px); } }
  @keyframes mbVtIn { from{ opacity:0; transform: translateY(8px);  } }
}
@media (prefers-reduced-motion: reduce){
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){ animation: none !important; }
}

/* CTA — stato :active (press tattile). hover/ombra/freccia già unificati in .mb-cta-btn */
.mb-cta-btn:active{ transform: translateY(0) scale(.97) !important; box-shadow: 0 4px 12px rgba(247,92,3,.22) !important; }
@media (prefers-reduced-motion: reduce){ .mb-cta-btn:active{ transform: none !important; } }


/* ============================================================================
   PRE-HIDE entrance GENERICO altre pagine (flash-free) — Innova, giu 2026.
   Hook class-based (NESSUNO styling visivo, solo opacity pre-paint), gated da
   mb-hero-pre come l'entrata home id-based. motion.js (setupHeroEntranceGeneric)
   anima, poi mb-hero-pre viene rimosso. In reduced-motion il <head> non mette
   mb-hero-pre -> elementi visibili, nessuna animazione.
   ============================================================================ */
html.mb-hero-pre .mb-anim-eyebrow,
html.mb-hero-pre .mb-anim-h1,
html.mb-hero-pre .mb-anim-claim,
html.mb-hero-pre .mb-anim-sub,
html.mb-hero-pre .mb-anim-cta,
html.mb-hero-pre .mb-anim-media{ opacity:0 !important; }
