/* ============================================================
   CONSTEC — motion.css (etapa 7, camada rica)
   Liga NOS GANCHOS deixados pela etapa 6. Não muda estrutura,
   não muda copy, não troca imagem.

   Tom: engenharia de precisão. Revelação por CORTE limpo, linha
   que desenha, deslocamento curto. Zero bounce, zero spring,
   zero flutuação. Duração/easing vêm de tokens.css.

   TRAVAS DESTE PROJETO
   · Scroll NATIVO (html{scroll-behavior:smooth} e ponto final).
   · Acervo em baixa resolução: PROIBIDO ampliar bitmap. Nenhum
     efeito aqui usa scale() em <img>. Movimento em mídia é
     máscara/clip/deslocamento do container.
   · Estado escondido só existe sob `html.js` (setado inline no
     <head>): sem JS, nada fica invisível.
   · Elemento position:sticky nunca recebe transform (o motion.js
     marca esses [data-reveal] com data-reveal-mode="fade").
   ============================================================ */

:root {
  --motion-on: 1;          /* sonda: prova por medição que esta folha carregou */
  --dur-wipe: 820ms;       /* corte de mídia            */
  --dur-hero: 1150ms;      /* cortina do hero           */
  --dur-draw: 1000ms;      /* linha/sublinhado desenhando */
}

/* ============================================================
   1 · REVEAL — entrada curta, só opacity + translateY
   ============================================================ */
html.js [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--dur-3) var(--ease), transform var(--dur-3) var(--ease);
  will-change: opacity, transform;
}
html.js [data-reveal].is-in { opacity: 1; transform: none; will-change: auto; }

/* pilha sticky: entrada SÓ por opacity (transform em sticky, ou em
   ancestral de sticky, quebra o grude). O motion.js marca sozinho. */
html.js [data-reveal][data-reveal-mode="fade"] { transform: none; will-change: opacity; }

html.js [data-reveal][data-delay="1"] { transition-delay: 110ms; }
html.js [data-reveal][data-delay="2"] { transition-delay: 220ms; }
html.js [data-reveal][data-delay="3"] { transition-delay: 330ms; }

/* ============================================================
   2 · CORTE DE MÍDIA — a assinatura do movimento
   Sem zoom: o bitmap nunca é ampliado, só desmascarado.
   Direção varia por família de bloco (movimento variado por seção).
   ============================================================ */

/* 2a · hero: cortina que desce (o corte abre de cima para baixo) */
html.js .hero__media {
  clip-path: inset(0 0 100% 0);
  transition: clip-path var(--dur-hero) var(--ease);
}
html.js .hero__media.is-in { clip-path: inset(0 0 0 0); }

/* 2b · capas e mosaicos: mesma cortina, escalonada */
html.js .folio__media,
html.js .scope__media .media,
html.js .case__thumbs .media,
html.js .mini .media {
  clip-path: inset(0 0 100% 0);
  transition: clip-path var(--dur-wipe) var(--ease);
}
html.js .folio__media.is-in,
html.js .scope__media .media.is-in,
html.js .case__thumbs .media.is-in,
html.js .mini .media.is-in { clip-path: inset(0 0 0 0); }

html.js .scope__media .media:nth-of-type(2) { transition-delay: 120ms; }
html.js .scope__media .media:nth-of-type(3) { transition-delay: 240ms; }
html.js .case__thumbs .media:nth-of-type(2) { transition-delay: 90ms; }
html.js .case__thumbs .media:nth-of-type(3) { transition-delay: 180ms; }
html.js .mini .media:nth-of-type(2) { transition-delay: 100ms; }

/* 2c · mídia editorial larga: corte lateral, da esquerda para a direita */
html.js .split__media .media,
html.js .caseband__media .media,
html.js .wide-media .media,
html.js .media[data-parallax] {
  clip-path: inset(0 100% 0 0);
  transition: clip-path var(--dur-wipe) var(--ease);
}
html.js .split__media .media.is-in,
html.js .caseband__media .media.is-in,
html.js .wide-media .media.is-in,
html.js .media[data-parallax].is-in { clip-path: inset(0 0 0 0); }

/* ============================================================
   3 · SUBLINHADO QUE DESENHA (destaque no H1)
   Filete bone de 2px, no mesmo peso dos filetes do design system.
   ============================================================ */
html.js [data-underline] {
  background-image: linear-gradient(var(--bone), var(--bone));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 2px;
  transition: background-size var(--dur-draw) var(--ease) 260ms;
}
html.js [data-underline].is-in { background-size: 100% 2px; }

/* ============================================================
   4 · LINHA QUE DESENHA (timeline / stepper)
   ============================================================ */
/* trilho horizontal da LP Empreiteira */
html.js .tl__rail .line { transform: scaleX(0); transition: transform var(--dur-draw) var(--ease); }
html.js .tl.is-drawn .tl__rail .line { transform: scaleX(1); }
@media (max-width: 900px) {
  html.js .tl__rail .line { transform: scaleY(0); }
  html.js .tl.is-drawn .tl__rail .line { transform: scaleY(1); }
}

/* fios verticais (fio condutor e passos do CTA) */
html.js .fio__line .line,
html.js .steps__line .line { transform: scaleY(0); transition: transform var(--dur-draw) var(--ease); }
html.js [data-timeline].is-drawn .fio__line .line,
html.js [data-timeline].is-drawn .steps__line .line { transform: scaleY(1); }

/* passos horizontais: o filete de 3px de cada passo cresce da esquerda */
html.js [data-timeline] .hsteps li::before {
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-2) var(--ease);
}
html.js [data-timeline].is-drawn .hsteps li::before { transform: scaleX(1); }
html.js [data-timeline].is-drawn .hsteps li:nth-child(2)::before { transition-delay: 140ms; }
html.js [data-timeline].is-drawn .hsteps li:nth-child(3)::before { transition-delay: 280ms; }

/* ============================================================
   5 · PARALLAX — só transform, e só no container
   O motion.js escreve translate3d no PRÓPRIO wrapper .media.
   Nada de background-position, nada de top, nada de scale:
   ampliar o bitmap estouraria o teto do MANIFESTO.
   ============================================================ */
html.js [data-parallax] { will-change: transform; }

/* ============================================================
   6 · HOVER DE CAPA — filete, não zoom
   O zoom de 1.06 da etapa 6 foi retirado do site.css: ampliar
   uma foto extraída de PDF passa do teto de nitidez. No lugar,
   o filete bone de 2px (mesmo elemento gráfico do card da marca).
   ============================================================ */
.folio__media::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 2px;
  background: var(--bone);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-2) var(--ease);
  pointer-events: none;
  z-index: 1;
}
.folio__card:hover .folio__media::after,
.folio__card:focus-within .folio__media::after { transform: scaleX(1); }

/* ============================================================
   7 · ABERTURA DO ACCORDION
   ============================================================ */
@keyframes cst-faq { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
html.js .faq__item.is-open .faq__a { animation: cst-faq var(--dur-2) var(--ease) both; }

/* ============================================================
   8 · FAIL-SAFE — sem JS, nada fica escondido
   (redundante de propósito: os estados fechados já são html.js)
   ============================================================ */
html:not(.js) [data-reveal] { opacity: 1 !important; transform: none !important; }
html:not(.js) .hero__media,
html:not(.js) .folio__media,
html:not(.js) .scope__media .media,
html:not(.js) .case__thumbs .media,
html:not(.js) .mini .media,
html:not(.js) .split__media .media,
html:not(.js) .caseband__media .media,
html:not(.js) .wide-media .media,
html:not(.js) .media[data-parallax] { clip-path: none !important; }
html:not(.js) [data-underline] { background-size: 100% 2px !important; }
html:not(.js) .tl__rail .line,
html:not(.js) .fio__line .line,
html:not(.js) .steps__line .line { transform: none !important; }

/* ============================================================
   9 · prefers-reduced-motion — estado final estático, nunca vazio
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html.js [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
  html.js .hero__media,
  html.js .folio__media,
  html.js .scope__media .media,
  html.js .case__thumbs .media,
  html.js .mini .media,
  html.js .split__media .media,
  html.js .caseband__media .media,
  html.js .wide-media .media,
  html.js .media[data-parallax] { clip-path: none !important; transition: none !important; }
  html.js [data-underline] { background-size: 100% 2px !important; transition: none !important; }
  html.js .tl__rail .line,
  html.js .fio__line .line,
  html.js .steps__line .line,
  html.js [data-timeline] .hsteps li::before { transform: none !important; transition: none !important; }
  html.js [data-parallax] { transform: none !important; will-change: auto; }
  html.js .faq__item.is-open .faq__a { animation: none !important; }
  .folio__media::after { transition: none !important; }
}
