/* =============================================================================
 * produto-3d.css — controles do visualizador 360° dos equipamentos
 * =============================================================================
 *  Par de js/produto-3d.js. Mesma convenção do eco-map3d.css (botões +/−/↻),
 *  mas em fundo CLARO: o palco do produto é claro, não o painel escuro do mapa.
 * ========================================================================== */

.produto-3d { position: relative; }

/* =========================================================================
 * MODO VITRINE — cards de produto da Home (.bento3d)
 * -------------------------------------------------------------------------
 * O card do bento é um <a> INTEIRO clicável e faz hover-fill (fica verde e o
 * texto inverte). O 3D aqui é VITRINE: gira sozinho, não tem botão e o canvas
 * é `pointer-events:none` (js/produto-3d.js, `data-modo="vitrine"`) — senão
 * arrastar p/ girar terminaria em clique e navegaria sem querer.
 * O equipamento assenta direto no fundo do card (renderer alpha) e a "sombra"
 * é CSS: no hover o card vira verde e a peça continua pousada, não recortada.
 * ====================================================================== */
/* 4 cards em `.bento{flex:1 1 30%}` davam 3 na 1ª linha e o 4º SOZINHO esticando
   pra largura toda (era a ETE virando faixa de 1072px — o print do Sérgio).
   2×2 equilibra e centraliza, e o card mais largo ainda comporta a vitrine. */
.bento3d{justify-content:center}
.bento3d .card{flex:1 1 44%;max-width:520px}
@media(max-width:620px){.bento3d .card{flex:1 1 100%}}

/* ===========================================================================
   VIDRO LÍQUIDO + PARALLAX 3D — cards de produto (ECOCASA)
   ---------------------------------------------------------------------------
   ⚠ A classe `.liquid-glass` NÃO é usada aqui, de propósito. Ela é (0,1,0) e
   define background/box-shadow/backdrop-filter: como a folha do liquid-glass
   é linkada DEPOIS desta, ela venceria e APAGARIA o tint da marca — foi assim
   que o FAB verde da ECOCASA virou branco (gotcha registrado na skill). A
   classe só serve pro `initAll()` achar o elemento; como o js/card-glass.js
   chama `window.liquidGlass(el)` na mão e os `data-lg-*` vêm do dataset, dá
   pra ficar com o vidro E com o CSS da marca.

   FUNDO: vidro refrata o que está ATRÁS. Sobre `--paper` liso não há o que
   refratar (só sobraria o rim light). Por isso a seção ganhou uma água ECOCASA
   atrás (`.bento-agua`): ondas concêntricas + brumas azul/lima — é ELA que
   entorta na borda do card e faz o efeito existir.
   ======================================================================== */
/* content-visibility: enquanto a seção não chega perto da viewport, o browser
   PULA layout/paint dela inteira. contain-intrinsic-size reserva a altura para o
   scrollbar não pular quando ela entra em cena. */
.sec-3d{position:relative;overflow:hidden;content-visibility:auto;contain-intrinsic-size:auto 1180px}
.bento-agua{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
/* brumas: dão cor de fundo pra seção.
   24/07 — o `filter: blur(38px)` saiu: era redundante (radial-gradient JÁ é
   suave, borrar um gradiente devolve quase o mesmo pixel) e obrigava o browser a
   manter duas camadas borradas de ~800×700 px. A transparência do gradiente foi
   esticada (72% -> 78%) para repor exatamente a maciez que o blur dava. */
.bento-agua::before,.bento-agua::after{content:"";position:absolute;border-radius:50%}
.bento-agua::before{width:52%;height:62%;left:-6%;top:6%;
  background:radial-gradient(closest-side,rgba(0,113,227,.22),transparent 78%)}
.bento-agua::after{width:56%;height:66%;right:-8%;bottom:-6%;
  background:radial-gradient(closest-side,rgba(114,159,40,.24),transparent 78%)}
/* ondas concêntricas = assinatura ECOCASA (mesma linguagem do .rings do hero) */
.bento-onda{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  border-radius:50%;border:1.5px solid rgba(11,61,44,.10)}
.bento-onda:nth-of-type(1){width:420px;height:420px}
.bento-onda:nth-of-type(2){width:760px;height:760px;border-color:rgba(0,113,227,.09)}
.bento-onda:nth-of-type(3){width:1120px;height:1120px;border-color:rgba(114,159,40,.10)}
.bento-onda:nth-of-type(4){width:1480px;height:1480px;border-color:rgba(11,61,44,.05)}
.sec-3d .wrap{position:relative;z-index:1}

/* ---- o card de vidro ---------------------------------------------------- */
.bento3d .card{
  /* tint da marca: o vidro é claro (cliente institucional), não escuro */
  /* 24/07/2026 — PERFORMANCE: o backdrop-filter saiu daqui (era blur(9px) e, no
     Chromium, a refração SVG injetada pelo card-glass.js). Custo altíssimo no
     scroll, ganho visual quase nulo: o fundo `.bento-agua` é gradiente radial
     sem aresta, e no hover o card vira sólido. Compensado subindo a opacidade do
     tint (.42 -> .62): sobre fundo suave, branco translúcido lê igual a fosco. */
  background:rgba(255,255,255,.62);
  border:1px solid rgba(255,255,255,.75);
  /* limita o repaint à caixa do card: sem isso, o brilho que segue o ponteiro
     convida o browser a repintar área além do card */
  contain:paint;
  box-shadow:0 16px 40px -18px rgba(11,61,44,.34),
             inset 1.5px 1.5px 1px rgba(255,255,255,.85),
             inset -1px -1.5px 1px rgba(255,255,255,.4),
             inset 0 0 18px rgba(255,255,255,.18);
  /* 23/07/2026 (Sérgio): "tira o efeito 3D, deixe só o parallax". Saíram o
     `perspective` e as rotações rotateX/rotateY — o card não inclina mais.
     O parallax FICA: as camadas continuam andando em profundidades diferentes,
     só que em translação pura (ver bloco das camadas abaixo). Motivo além do
     gosto: rotacionar um card grande com texto força o navegador a rasterizar
     a subárvore inteira a cada frame, e era parte do "trava o site". */
  transition:box-shadow .45s var(--ease),background .45s var(--ease),border-color .45s var(--ease)}

/* hover: o card PREENCHE de verde escuro da marca (Sérgio 23/07: "ao passar o
   mouse muda de cor, do branco pra aquele verde escuro"). Isso substitui o
   hover "de vidro" que havia aqui — sólido mata a refração, e é a troca que ele
   pediu. Por isso todo o conteúdo inverte junto: com o fundo escuro, texto
   verde/cinza ficaria ilegível. */
.bento3d .card:hover{
  background:var(--verde);
  border-color:rgba(169,207,91,.42);
  box-shadow:0 30px 60px -22px rgba(8,42,30,.55),
             inset 0 0 0 1px rgba(169,207,91,.16)}
.bento3d .card:hover h3{color:#fff}
.bento3d .card:hover p{color:rgba(255,255,255,.80)}
.bento3d .card:hover .more{color:var(--lima-soft)}
.bento3d .card:hover .ghost{color:rgba(255,255,255,.10)}
/* brilho especular que segue o ponteiro */
.bento3d .card .card-luz{position:absolute;inset:0;z-index:3;pointer-events:none;opacity:0;
  border-radius:inherit;transition:opacity .4s var(--ease);mix-blend-mode:overlay;
  background:radial-gradient(420px 300px at calc(var(--mx,50%)) calc(var(--my,50%)),
             rgba(255,255,255,.75),rgba(255,255,255,.14) 44%,transparent 70%)}
.bento3d .card.is-tilt .card-luz{opacity:1}

/* ---- camadas em profundidade (o parallax) -------------------------------
   Era translate3d com Z (a profundidade vinha do `perspective` do card). Sem o
   tilt não há perspectiva, então o Z só custava composição sem aparecer: virou
   translação 2D pura. A SENSAÇÃO de profundidade continua e é a mesma de antes
   — ela nunca veio do Z, veio das camadas andarem em amplitudes diferentes
   (o número fantasma anda ao contrário e mais longe; o produto e o "saiba mais"
   andam mais; o parágrafo quase não anda). */
.bento3d .card .ghost{transform:translate(calc(var(--px,0) * -16px),calc(var(--py,0) * -11px))}
.bento3d .card .card-vitrine{transform:translate(calc(var(--px,0) * 9px),calc(var(--py,0) * 6px))}
.bento3d .card h3{position:relative;transform:translate(calc(var(--px,0) * 8px),calc(var(--py,0) * 5px))}
.bento3d .card p{transform:translate(calc(var(--px,0) * 5px),calc(var(--py,0) * 3px))}
.bento3d .card .more{transform:translate(calc(var(--px,0) * 9px),calc(var(--py,0) * 6px))}
/* A transição agora é DE CADA CAMADA. Antes elas pegavam carona no `transform`
   do card (que tinha `transition:transform .55s`); sem o tilt esse transform
   não existe mais, e sem isto as camadas voltariam ao centro com um salto seco
   quando o ponteiro sai. Curta e linear enquanto o ponteiro está em cima
   (acompanhar tem que ser imediato), longa e com ease na volta. */
.bento3d .card .ghost,.bento3d .card .card-vitrine,.bento3d .card h3,
.bento3d .card p,.bento3d .card .more{transition:transform .55s var(--ease)}
.bento3d .card.is-tilt .ghost,.bento3d .card.is-tilt .card-vitrine,
.bento3d .card.is-tilt h3,.bento3d .card.is-tilt p,
.bento3d .card.is-tilt .more{transition:transform .12s linear}

.card-vitrine{position:relative;height:186px;margin:-6px 0 16px;
  display:grid;place-items:center;isolation:isolate}

/* ---- a FOTO do produto (era um viewer WebGL) -----------------------------
   Sérgio 23/07/2026: "o produto não precisa ser em 3D que precisa se mexer,
   pode ser uma foto do 3D que fizemos — assim fica menos pesado e não trava
   tanto o site". A foto é gerada DO PRÓPRIO modelo 3D (scratchpad/render-cards.py
   captura o canvas), então é o mesmo produto, mesma luz, mesmas logos — só que
   custa ~30 kB em vez de um contexto WebGL por card.
   O que a home deixou de fazer: baixar three.js + produto-3d.js e manter 4
   renderers vivos rodando rAF (5 em produtos.html).
   WebP com ALFA de propósito: a sombra de contato vem no canal alfa
   (ShadowMaterial), então a MESMA imagem assenta no card branco e no verde do
   hover. Um PNG chapado exigiria duas artes. */
/* ⚠ `position:absolute` NÃO é detalhe — é o que prende a foto ao palco.
   Com `position:relative` (como ficou na 1ª versão) a foto vira GRID ITEM, e aí
   `height:100%` resolve contra a LINHA da grade... que cresce com o conteúdo.
   Ou seja: a linha esticava até a altura natural da imagem (245px num palco de
   168px) e a foto passava POR CIMA do título. Fora do fluxo, a linha não cresce
   e `inset:0` fixa a caixa no palco. Medido: transbordo de 77px → 0. */
.card-vitrine .card-render{position:absolute;inset:0;z-index:1;
  width:100%;height:100%;object-fit:contain;padding:8px;
  /* a sombra do render some sobre o verde escuro: este drop-shadow devolve o
     contato no hover, sem precisar de segunda arte */
  filter:drop-shadow(0 10px 12px rgba(8,42,30,.28));
  transition:filter .35s var(--ease),transform .5s var(--ease)}
.card:hover .card-vitrine .card-render{filter:drop-shadow(0 12px 16px rgba(0,0,0,.42))}
/* halo sutil atrás da peça, p/ ela não sumir no verde do hover */
.card-vitrine::before{content:"";position:absolute;inset:8% 12%;z-index:0;border-radius:50%;
  background:radial-gradient(closest-side,rgba(0,113,227,.09),transparent 72%);
  opacity:0;transition:opacity .35s var(--ease)}
.card.esg .card-vitrine::before{background:radial-gradient(closest-side,rgba(169,207,91,.14),transparent 72%)}
.card:hover .card-vitrine::before{opacity:1}

/* Saíram daqui, em 23/07: `.card-vitrine::after` (a elipse de chão em CSS) e
   `.card-foto`. A elipse virava sombra DUPLICADA agora que a foto já traz a
   sua no alfa; `.card-foto` era o caso especial da ETE, que hoje tem modelo
   próprio (`montarEte`) e usa a mesma `.card-render` dos outros. Conferido:
   nenhum HTML do site referencia `.card-foto`. */

@media(max-width:620px){ .card-vitrine{height:170px} }
@media(prefers-reduced-motion:reduce){
  .card-vitrine::before{transition:none}
  .bento3d .card .ghost,.bento3d .card .card-vitrine,.bento3d .card h3,
  .bento3d .card p,.bento3d .card .more{transform:none}
}

/* ---- HERO com 3D --------------------------------------------------------
 * O hero do produto é texto centralizado em fundo escuro. Para caber o 3D ele
 * vira DUAS COLUNAS no desktop (texto à esquerda, equipamento à direita) e
 * volta a empilhar no mobile — no celular o 3D entra DEPOIS do texto e das
 * CTAs, senão empurra a chamada e o botão para baixo da dobra.
 * ---------------------------------------------------------------------- */
.hero.hero3d { text-align: left; }
/* ⚠ o TEXTO tem que estar embrulhado em .hero-3d-txt. Sem isso, cada filho de
 * .inner (eyebrow, h1, sub, cta, badge, chips) vira uma CÉLULA do grid e o hero
 * se espalha — o h1 vai pra direita, o subtítulo pra baixo. Aconteceu. */
.hero.hero3d .inner {
  max-width: 1200px; width: 100%;
  display: grid; gap: 30px; align-items: center;
}
.hero.hero3d .hero-3d-txt { min-width: 0; order: 1; }
.hero.hero3d .eyebrow.center { justify-content: flex-start; }
.hero.hero3d .cta { justify-content: flex-start; }
.hero.hero3d .sub { margin-left: 0; margin-right: 0; }

.hero-3d-palco {
  position: relative; min-height: 340px; order: 2;
  /* sem fundo próprio: o equipamento assenta no gradiente do próprio hero */
}
.hero-3d-palco .produto-3d { height: 100%; min-height: 340px; background: none; }
.hero-3d-palco .produto-3d img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; padding: 8px;
}

@media (min-width: 980px) {
  .hero.hero3d { text-align: left; }
  .hero.hero3d .inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: 44px; }
  .hero-3d-palco { min-height: 460px; }
  .hero-3d-palco .produto-3d { min-height: 460px; }
}
@media (max-width: 979px) {
  .hero.hero3d { text-align: center; }
  .hero.hero3d .eyebrow.center { justify-content: center; }
  .hero.hero3d .cta { justify-content: center; }
  .hero.hero3d .sub { margin-left: auto; margin-right: auto; }
  .hero-3d-palco { min-height: 300px; }
}

/* No hero escuro os botões claros somem — inverte. */
.hero-3d-palco .produto-3d-btn {
  background: rgba(255, 255, 255, .12);
  border-color: rgba(255, 255, 255, .26);
  color: #fff;
}
.hero-3d-palco .produto-3d-btn:hover {
  background: rgba(169, 207, 91, .45);
  border-color: rgba(199, 238, 134, .75);
}
/* ⚠ `.produto-3d` no meio NÃO é enfeite: o bloco canônico da dica (mais abaixo)
 * declara `color: var(--muted)` com a mesma especificidade que `.hero-3d-palco
 * .p3d-hint` e vem DEPOIS no arquivo — no empate ele vencia e a dica saía
 * cinza-escuro sobre o hero verde-escuro, ilegível. Medido no DOM pintado. */
.hero-3d-palco .produto-3d .p3d-hint { color: rgba(255, 255, 255, .66); }

/* ---- controles de zoom ---------------------------------------------------- */
.produto-3d-ctr {
  position: absolute; right: 10px; bottom: 10px; z-index: 3;
  display: flex; flex-direction: column; gap: 6px;
}
.produto-3d-btn {
  width: 34px; height: 34px; border-radius: 10px; cursor: pointer;
  border: 1px solid rgba(11, 61, 44, .14);
  background: rgba(255, 255, 255, .82);
  color: var(--verde, #0B3D2C);
  font: 600 16px/1 'Montserrat', sans-serif;
  display: grid; place-items: center;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 1px 2px rgba(11, 61, 44, .06), 0 6px 16px -8px rgba(11, 61, 44, .28);
  transition: background .18s var(--ease, ease), transform .18s var(--ease, ease),
              border-color .18s var(--ease, ease);
}
.produto-3d-btn:hover {
  background: rgba(169, 207, 91, .5);
  border-color: rgba(114, 159, 40, .55);
  transform: translateY(-1px);
}
.produto-3d-btn:active { transform: translateY(0) scale(.94); }
.produto-3d-btn:focus-visible { outline: 2px solid var(--lima, #729F28); outline-offset: 2px; }

/* ---- crossfade poster → 3D ------------------------------------------------
 * Antes o <img> era escondido no instante em que o canvas subia: a página
 * "piscava" (foto some → hero vazio → tanque aparece), lido como cache velho.
 * Agora o canvas nasce invisível e o JS marca .p3d-live no PRIMEIRO frame com
 * o modelo montado — foto e 3D se cruzam em fade. Sem WebGL nada disso roda. */
.produto-3d canvas { opacity: 0; transition: opacity .7s var(--ease, ease) }
.produto-3d.p3d-live canvas { opacity: 1 }
.produto-3d img { transition: opacity .7s var(--ease, ease) }
.produto-3d.p3d-live img { opacity: 0 }

/* indicador discreto de "3D carregando" enquanto o Three sobe */
.produto-3d.p3d-boot:not(.p3d-live)::after {
  content: ''; position: absolute; top: 14px; right: 14px; z-index: 4;
  width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .28); border-top-color: rgba(255, 255, 255, .9);
  animation: p3dSpin .8s linear infinite;
}
@keyframes p3dSpin { to { transform: rotate(360deg) } }

/* ---- dica de uso: "arraste para girar…" ------------------------------------
   Sérgio 23/07/2026. O texto vem do JS (fonte única); aqui fica só a aparência.
   ⚠ Seletor com .produto-3d na frente DE PROPÓSITO: o <style> inline do
   3d-produtos.html declara `.p3d-hint{position:absolute;…}` e vem DEPOIS deste
   arquivo — com 0,1,0 contra 0,2,0 este vence mesmo assim. Antes desta regra as
   5 páginas de PRODUTO herdavam só a cor e a dica caía no fluxo, como texto
   solto embaixo do palco 3D. */
.produto-3d .p3d-hint {
  position: absolute; left: 0; right: 0; bottom: 10px; z-index: 3;
  text-align: center; pointer-events: none;
  font: 300 11.5px/1.45 'Montserrat', system-ui, sans-serif;
  letter-spacing: .3px; color: var(--muted, #5A6B62);
  padding: 0 46px;                 /* não passa por baixo dos botões +/−/↻ */
  transition: opacity .3s var(--ease, ease);
}
.produto-3d .p3d-hint i { font-style: normal; }
/* ponteiro fino (mouse) vê "role"; touch vê "pince" — sem sniffing de userAgent */
.produto-3d .p3d-h-toque { display: none; }
@media (hover: none) {
  .produto-3d .p3d-h-mouse { display: none; }
  .produto-3d .p3d-h-toque { display: inline; }
  .produto-3d .p3d-hint { font-size: 11px; padding: 0 44px 0 12px; }
}
/* no hero escuro o --muted some: a cor clara vem de .hero-3d-palco (acima) */
.hero-3d-palco .p3d-hint { text-shadow: 0 1px 2px rgba(0, 0, 0, .35); }
/* some na 1ª interação (já usou, já sabe) e volta no ↻ */
.produto-3d.is-zoomed .p3d-hint,
.produto-3d.p3d-assumido .p3d-hint { opacity: 0; }

/* ---- splash de carregamento: o LOGO -------------------------------------------
   Henrique 17/07: "nessa imagem de carregamento, em vez de deixar uma imagem do
   produto, põe só o logo (...) aumenta pouquinho, uns três segundinhos, pra dar
   tempo de ler o logo".
   ⚠ É uma CAMADA POR CIMA, não a troca do <img>: o <img> do produto continua
   sendo o fallback de quem não tem WebGL — trocá-lo pelo logo deixaria esse
   usuário sem ver o produto nunca. O JS só injeta o splash quando o renderer
   vai mesmo subir, então sem WebGL nada disso aparece.
   Seletor com .produto-3d na frente de propósito: o <style> inline do
   3d-produtos.html tem `.produto-3d img{position:absolute;padding:22px}` e vem
   DEPOIS deste arquivo — no empate de especificidade ele venceria. */
/* Sérgio 20/07/2026: "somente as logos, sem fundo branco". O retângulo --paper
   atrás da logo destoava do hero verde. Agora o splash é TRANSPARENTE.

   Duas consequências que precisaram ser resolvidas junto:

   1) sem o fundo, a FOTO do produto (o <img> de fallback, que fica visível até o
      canvas subir) aparecia atrás da logo — logo sobre foto, ilegível. Daí o
      `.p3d-splashing > img{opacity:0}`: o filho DIRETO some, a logo (que é neta,
      vive dentro do .p3d-splash) fica.

   2) o fundo atrás do splash NÃO é constante — medido: verde escuro (luma 49) na
      oasis, quase branco (247/253) na cisterna e na ecoted, porque o palco tem
      min-height 460px e transborda o hero para a seção clara de baixo. As logos
      têm luma média 137–177, então no escuro contrastam bem e no claro ficariam
      moles. O drop-shadow resolve os dois casos sem reintroduzir caixa: no claro
      ele destaca a silhueta, no escuro não aparece. */
.produto-3d .p3d-splash {
  position: absolute; inset: 0; z-index: 3; display: grid; place-items: center;
  background: transparent;
  transition: opacity .8s var(--ease, ease);
}
.produto-3d.p3d-splashing > img { opacity: 0; transition: opacity .3s var(--ease, ease); }
/* `.produto-3d.p3d-live img{opacity:0}` (lá em cima) usa seletor DESCENDENTE: foi
   escrito para apagar a foto de fallback quando o canvas assume, mas alcança
   qualquer <img> dentro do viewer — inclusive a logo do splash. Resultado: ao
   virar live, a logo apagava SOZINHA em vez de sair junto com o splash. Aqui ela
   volta a 1 e quem controla a saída é a opacity do container, como deve ser. */
.produto-3d.p3d-live .p3d-splash img { opacity: 1; }
.produto-3d .p3d-splash img {
  position: static; inset: auto; padding: 0;
  width: min(58%, 210px); height: auto; object-fit: contain;
  filter: drop-shadow(0 2px 10px rgba(8, 42, 30, .28))
          drop-shadow(0 1px 2px rgba(8, 42, 30, .18));
  animation: p3dSplashIn .7s var(--ease, ease) backwards;
}
@keyframes p3dSplashIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.produto-3d .p3d-splash.p3d-splash-out { opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .produto-3d .p3d-splash img { animation: none; } }

/* Sem WebGL o <img> de fallback fica; aí os botões não fazem sentido.
   O JS só injeta .produto-3d-ctr depois que o renderer sobe, então nada a fazer
   aqui — mas se o canvas não existir, esconde por garantia. */
.produto-3d:not(:has(canvas)) .produto-3d-ctr { display: none; }

@media (prefers-reduced-motion: reduce) {
  .produto-3d-btn { transition: none; }
  .produto-3d canvas, .produto-3d img { transition: none; }
  .produto-3d.p3d-boot:not(.p3d-live)::after { animation: none; display: none; }
}
