/* ═══════════════════════════════════════════════════════════════
   BIBLIOTECA DE EFEITOS · Coisas de Crianças
   Versão 1 · 12/09/2026

   Regra número um, e ela não se negocia:
   O ESTADO BASE É O ESTADO FINAL LEGÍVEL. Nenhum efeito esconde
   conteúdo. Se o navegador não souber animar, ou se a pessoa pediu
   menos movimento, a página fica pronta e parada — nunca vazia.

   Por isso todo efeito de rolagem mora dentro de
   @supports (animation-timeline: view()) + prefers-reduced-motion.
   O Firefox ainda não tem animation-timeline (set/2026); nele o
   site simplesmente não anima, e continua inteiro.

   Aplicação: data-fx="nome" no elemento.
   Desligar tudo: data-cinema="nao" na raiz.
   ═══════════════════════════════════════════════════════════════ */

:root{
  --fx-r: 160ms;              /* resposta curta  — NN/g: feedback ~100ms  */
  --fx-t: 260ms;              /* transição média — NN/g: 200–300ms       */
  --fx-e: cubic-bezier(.22,1,.36,1);
}
[data-cinema="nao"]{ --fx-r:0ms; --fx-t:0ms }

/* ───────────────────────────────────────────────────────────────
   CAMADA A — custo zero, sempre ligada, sem JS.
   É aqui que mora a maior parte da sensação de acabamento.
   ─────────────────────────────────────────────────────────────── */

/* tipografia que se equilibra sozinha — sem custo, sem risco */
h1,h2,h3,.display,.lead{ text-wrap:balance }
p,.corpo,.item-desc{ text-wrap:pretty }

/* trilho de leitura no topo da página */
.fx-trilho{
  position:fixed; inset:0 0 auto 0; height:3px; z-index:400;
  transform-origin:0 50%; transform:scaleX(0);
  background:linear-gradient(90deg,var(--rosa),var(--azul),var(--verde),var(--amarelo),var(--coral));
  pointer-events:none;
}
@supports (animation-timeline: scroll()){
  .fx-trilho{ animation:fx-trilho linear both; animation-timeline:scroll(root block) }
}
@keyframes fx-trilho{ from{transform:scaleX(0)} to{transform:scaleX(1)} }

/* cabeçalho que ganha sombra quando gruda no topo.
   scroll-state() só existe no Chrome 133+; sem ele, nada acontece
   e o cabeçalho fica como sempre foi. Degradação limpa. */
.topo{ container-type:scroll-state }
@container scroll-state(stuck: top){
  .topo{ box-shadow:0 8px 26px -14px rgba(0,0,0,.7) }
}

/* lista que rola de lado avisa que tem mais coisa */
.fx-borda-rolo{ container-type:scroll-state; position:relative }
@container scroll-state(scrollable: right){
  .fx-borda-rolo::after{ opacity:1 }
}

/* ───────────────────────────────────────────────────────────────
   CAMADA B — dirigidos pela rolagem.
   Todos compositor (transform/opacity), salvo onde dito.
   ─────────────────────────────────────────────────────────────── */

@supports (animation-timeline: view()){
 @media all /* era prefers-reduced-motion: quem manda é o botão Cinema */{
  [data-cinema="sim"] [data-fx]{ animation-fill-mode:both; animation-timing-function:linear }

  /* SOBE — o bloco chega subindo e para. Não repete ao sair.
     O animation-range é o que impede o "tudo se monta de novo",
     que é a reclamação registrada pela NN/g. */
  [data-cinema="sim"] [data-fx="sobe"]{
    animation-name:fx-sobe; animation-timeline:view(); animation-range:entry 12% entry 86%;
  }
  /* CASCATA — os filhos entram um atrás do outro */
  [data-cinema="sim"] [data-fx="cascata"] > *{
    animation:fx-sobe linear both; animation-timeline:view(); animation-range:entry 10% entry 82%;
    animation-delay:calc(var(--fx-i,0) * 55ms);
  }
  /* RESPIRA — a foto cresce devagar enquanto a seção passa (Ken Burns) */
  [data-cinema="sim"] [data-fx="respira"]{
    animation-name:fx-respira; animation-timeline:view(); animation-range:cover;
  }
  /* CHEGA — escala grande que assenta. É o do vídeo de referência. */
  [data-cinema="sim"] [data-fx="chega"]{
    animation-name:fx-chega; animation-timeline:view(); animation-range:entry 0% cover 60%;
  }
  /* MÁSCARA — o texto é revelado por um corte que abre.
     Não fatia o HTML: a quebra de linha continua livre. */
  [data-cinema="sim"] [data-fx="mascara"]{
    animation-name:fx-mascara; animation-timeline:view(); animation-range:entry 18% entry 92%;
  }
  /* FOCO — a foto sai do desfoque. Custo de GPU proporcional à ÁREA:
     raio limitado a 12px e só em foto de destaque, nunca em grade. */
  [data-cinema="sim"] [data-fx="foco"]{
    animation-name:fx-foco; animation-timeline:view(); animation-range:entry 0% entry 72%;
  }
  /* CORTINA — o painel desce e descobre a seção */
  [data-cinema="sim"] [data-fx="cortina"]{
    animation-name:fx-cortina; animation-timeline:view(); animation-range:entry 0% contain 30%;
  }
  /* DESLIZA — parallax honesto: só transform, nunca background-position */
  [data-cinema="sim"] [data-fx="desliza"]{
    animation-name:fx-desliza; animation-timeline:view(); animation-range:cover;
  }
 }
}

@keyframes fx-sobe   { from{opacity:0; transform:translateY(22px)} to{opacity:1; transform:none} }
@keyframes fx-respira{ from{scale:1; translate:0 -1.5%} to{scale:1.1; translate:0 1.5%} }
@keyframes fx-chega  { from{transform:scale(1.13)} to{transform:scale(1)} }
@keyframes fx-mascara{ from{clip-path:inset(0 100% 0 0); opacity:.25} to{clip-path:inset(0 0 0 0); opacity:1} }
@keyframes fx-foco   { from{filter:blur(12px) saturate(.62); scale:1.06} to{filter:blur(0) saturate(1); scale:1} }
@keyframes fx-cortina{ from{clip-path:inset(100% 0 0 0)} to{clip-path:inset(0 0 0 0)} }
@keyframes fx-desliza{ from{translate:0 -7%} to{translate:0 7%} }

/* ── EMPILHA e PRESO — APOSENTADOS EM 17/09/2026 ───────────────
   DEFEITO MEDIDO, foto do dono: uma faixa de texto branco enorme no
   meio da página e o texto da seção do urso começando no meio de uma
   frase. Causa: ele experimentou estes dois efeitos no Estúdio.

   Os dois cortavam conteúdo — `overflow:clip` e, no PRESO,
   `max-height:100dvh`. Numa seção mais alta que a tela, o que sobra
   some, e sobra buraco branco no lugar. Isso viola a regra número um
   desta biblioteca, escrita no topo deste arquivo: NENHUM EFEITO
   ESCONDE CONTEÚDO.

   Eles fazem sentido numa seção desenhada para isso — cartões curtos
   e do mesmo tamanho —, não como opção solta para qualquer faixa. Por
   isso saíram da lista do editor, e as regras ficam aqui neutras: se
   um "empilha" ou um "preso" tiver sobrado guardado em algum rascunho
   ou no #ajustes, ele não corta nada — simplesmente não faz efeito.  */
[data-fx="empilha"],[data-fx="preso"]{
  overflow:visible !important; max-height:none !important; position:static !important;
}
[data-fx="empilha"] > *{ position:static !important }

/* ───────────────────────────────────────────────────────────────
   CAMADA C — só computador, só com mouse fino.
   pointer:coarse é dedo; hover:none é sem hover. Testar largura de
   tela não serve: tablet com caneta cai no lugar errado.
   ─────────────────────────────────────────────────────────────── */
@media (hover:hover) and (pointer:fine){
  [data-cinema="sim"] .fx-ima{
    transform:translate(var(--mx,0px), var(--my,0px));
    transition:transform var(--fx-t) var(--fx-e);
  }
  [data-cinema="sim"] .fx-luz{ position:relative; isolation:isolate }
  [data-cinema="sim"] .fx-luz::before{
    content:""; position:absolute; inset:-1px; z-index:-1; border-radius:inherit;
    pointer-events:none; opacity:0; transition:opacity var(--fx-t);
    background:radial-gradient(220px circle at var(--lx,50%) var(--ly,50%),
               color-mix(in oklab, var(--amarelo) 42%, transparent), transparent 70%);
  }
  [data-cinema="sim"] .fx-luz:hover::before{ opacity:1 }
}

/* ───────────────────────────────────────────────────────────────
   TRANSIÇÃO ENTRE PÁGINAS (View Transitions, mesma página)
   A foto do produto na grade cresce e vira a foto grande.
   91,75% dos navegadores. Onde não tem, a troca é instantânea —
   que é exatamente o que acontecia antes.
   ─────────────────────────────────────────────────────────────── */
@media all /* era prefers-reduced-motion: quem manda é o botão Cinema */{
  ::view-transition-old(root){ animation:fx-sai 150ms ease-out both }
  ::view-transition-new(root){ animation:fx-entra 220ms ease-out both }
}
:root[data-cinema="nao"]::view-transition-old(root),
:root[data-cinema="nao"]::view-transition-new(root){ animation:none }
@keyframes fx-sai  { to  { opacity:0 } }
@keyframes fx-entra{ from{ opacity:0 } }
/* o snapshot estica por padrão; sem isto a foto entra deformada */
::view-transition-old(foto-heroi),::view-transition-new(foto-heroi){
  object-fit:cover; height:100%;
}

/* ───────────────────────────────────────────────────────────────
   DESLIGAR
   Uma chave só mata tudo. E sob prefers-reduced-motion o que era
   deslocamento vira aparecimento simples — não some nada.
   ─────────────────────────────────────────────────────────────── */
[data-cinema="nao"] [data-fx],
[data-cinema="nao"] [data-fx="cascata"] > *{
  animation:none !important; opacity:1 !important;
  transform:none !important; scale:none !important; translate:none !important;
  clip-path:none !important; filter:none !important;
}
/* 17/09: era @media (prefers-reduced-motion: reduce). Agora quem
   desliga é o botão Cinema — a regra [data-cinema="nao"] acima já
   cobre estes quatro efeitos junto com todos os outros. */

/* ───────────────────────────────────────────────────────────────
   COMPATIBILIDADE — as peças que já existiam na página antes da
   biblioteca. Quem não tem data-fx próprio herda um padrão.
   ─────────────────────────────────────────────────────────────── */
@supports (animation-timeline: view()){
 @media all /* era prefers-reduced-motion: quem manda é o botão Cinema */{
  [data-cinema="sim"] .item-foto:not([data-fx]),
  [data-cinema="sim"] .cine:not([data-fx]){
    animation:fx-chega linear both; animation-timeline:view(); animation-range:entry 0% cover 60%;
  }
 }
}
[data-cinema="nao"] .item-foto,[data-cinema="nao"] .cine{
  animation:none !important; transform:none !important; opacity:1 !important;
}
@media print{ #est-folha,#est-liga,#est-mira,#est-recado,.fx-trilho{ display:none !important } }

/* ═══════════════════════════════════════════════════════════════
   ABERTURA — a marca se reconstruindo
   13/09/2026

   O selo original foi separado em quatro camadas, recortadas do
   próprio arquivo: a cena em aquarela, a linha "COISAS DE", a
   linha "CRIANÇAS" e a assinatura. Nada foi redesenhado; cada
   camada é um pedaço do arquivo oficial com o fundo branco da
   placa removido.

   Elas chegam na ordem em que alguém desenharia a marca: a placa,
   a cena, o nome linha a linha, e a assinatura por último.

   Estado base = marca inteira, parada e visível. A animação só
   existe dentro do @media de movimento — sem ela, a página abre
   com a marca montada.
   ═══════════════════════════════════════════════════════════════ */

/* --topo-alt é a altura real do cabeçalho grudado, medida no
   carregamento. Sem ela o "role" do pé da cena cai atrás da dobra,
   justamente a coisa que manda a pessoa rolar. Recuo 0px: sem JS a
   cena fica 100svh, que é grande demais mas nunca esconde nada. */
.abertura{
  min-height:calc(100svh - var(--topo-alt, 0px));
  display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:clamp(18px,3.2vh,40px);
  padding-block:clamp(30px,5vh,70px);
}
.selo-cena{
  position:relative; width:min(70vw,min(54vh,520px)); aspect-ratio:1/1;
  flex:none; isolation:isolate;
}
.selo-placa{
  position:absolute; inset:0; border-radius:50%; background:#fff;
  box-shadow:0 26px 70px -30px rgba(0,0,0,.6);
}
.selo-cena img{ position:absolute; height:auto; display:block; max-width:none }
/* posição e tamanho medidos no próprio arquivo, em % do círculo.
   Especificidade igual à da regra de cima, senão ela ganha e todas
   as camadas saem do tamanho do círculo — foi o que aconteceu. */
.selo-cena img.sc-cena { left:11.986%; top:3.321%; width:77.617% }
.selo-cena img.sc-l1 { left:13.863%; top:48.592%; width:72.058% }
.selo-cena img.sc-l2 { left:13.069%; top:61.805%; width:74.368% }
.selo-cena img.sc-as { left:14.007%; top:76.029%; width:72.924% }
/* O urso fica EXATAMENTE por cima do urso que já está na aquarela. Com a
   logo parada ninguém vê diferença — ele só existe para poder sair. */
.selo-cena img.sc-urso { left:33.720%; top:26.501%; width:17.617% }

.abertura-fala{
  font-family:var(--ff-titulo),sans-serif; font-weight:600;
  font-size:clamp(15px,2.1vw,21px); letter-spacing:-.01em;
  text-align:center; max-width:34ch; color:var(--sobre-suave,inherit);
}
.abertura-desce{
  display:inline-flex; flex-direction:column; align-items:center; gap:8px;
  font-family:"DM Mono",monospace; font-size:11.5px; letter-spacing:.14em;
  text-transform:uppercase; opacity:.7;
}
.abertura-desce::after{
  content:""; width:1px; height:26px; background:currentColor;
}

@media all /* era prefers-reduced-motion: quem manda é o botão Cinema */{
  .abertura .selo-placa{ animation:ab-placa 760ms cubic-bezier(.2,.8,.25,1) both }
  .abertura .sc-cena  { animation:ab-cena  900ms cubic-bezier(.2,.8,.25,1) 220ms both }
  .abertura .sc-l1    { animation:ab-sobe  620ms cubic-bezier(.2,.9,.25,1) 620ms both }
  .abertura .sc-l2    { animation:ab-sobe  620ms cubic-bezier(.2,.9,.25,1) 790ms both }
  .abertura .sc-as    { animation:ab-tinta 720ms ease-out 1020ms both }
  .abertura-fala      { animation:ab-tinta 700ms ease-out 1320ms both }
  .abertura-desce     { animation:ab-tinta 700ms ease-out 1600ms both }
  /* e a marca inteira encolhe de leve quando a página começa a rolar */
  @supports (animation-timeline: view()){
    [data-cinema="sim"] .abertura .selo-cena{
      animation:ab-recolhe linear both;
      animation-timeline:view(); animation-range:exit 0% exit 100%;
    }
  }
}
@keyframes ab-placa { from{opacity:0; transform:scale(.84)} to{opacity:1; transform:none} }
@keyframes ab-cena  { from{opacity:0; transform:scale(.93) translateY(6%)} to{opacity:1; transform:none} }
@keyframes ab-sobe  { from{opacity:0; transform:translateY(46%)} to{opacity:1; transform:none} }
@keyframes ab-tinta { from{opacity:0} to{opacity:1} }
@keyframes ab-recolhe{ to{ transform:scale(.72); opacity:.35 } }

[data-cinema="nao"] .abertura *{
  animation:none !important; opacity:1 !important; transform:none !important;
}

/* ═══════════════════════════════════════════════════════════════
   O FILME DA ABERTURA — 14/09/2026, pedido do dono
   "COLOQUE ESSA ANIMAÇÃO NA ENTRADA SERIA O HOME DA PÁGINA"

   ANTES → a abertura remontava o SELO REDONDO em camadas (.selo-cena).
   NOVA DECISÃO → a abertura é o filme de 18s da logo colorida.
   MOTIVO → o dono mandou o vídeo pronto e pediu ele na entrada.
   DATA → 14/09/2026.
   A cena em camadas NÃO foi apagada: virou a segunda opção, e o
   Estúdio troca entre as duas. Registro em
   design/abertura-filme-da-logo.md.

   DOIS ENCAIXES DA MESMA MARCA: o filme termina na logo SEM o círculo.
   O cabeçalho e o rodapé continuam com o SELO REDONDO (CONFIRMADO
   12/09) — é a mesma arte, dentro de um círculo. Ter as duas versões é
   normal num sistema de identidade, mas qual manda em qual lugar é
   decisão do dono. Nenhum agente troca o logo por iniciativa própria.

   POR QUE O FILME TEM CHAPA PRÓPRIA: o vídeo é h264, que não carrega
   transparência. O fundo dele é #FAF9F5 — quase o papel da marca. Se
   eu jogasse o quadrado solto sobre a banda, ele viraria uma caixa
   branca em cima da tinta escura ou em cima do arco-íris que o dono
   ligou. Então o filme se apresenta como o que ele é: uma CHAPA DE
   PAPEL apoiada na banda, com canto arredondado e sombra. Assim
   funciona com qualquer paleta e com qualquer pintura de fundo, sem
   desligar nenhuma escolha dele.
   ═══════════════════════════════════════════════════════════════ */

/* Estado base = logo pronta e legível. O <video> carrega poster com o
   ÚLTIMO quadro: sem JS, sem rede para o vídeo, ou com movimento
   reduzido, quem chega já vê a marca inteira. O filme só acrescenta.

   SEM MOLDURA — decisão do dono, 15/09/2026.
   ANTES: o filme vinha numa chapa de papel com canto e sombra, de
   ~74vw. Medido no celular dele (390x844): a logo dava 289px com 170px
   de vazio em cima e 164px embaixo — virava um selinho no meio de uma
   lavagem pálida.
   NOVA DECISÃO: a banda inteira passa a ser o creme do próprio filme e
   o filme ocupa a entrada de ponta a ponta. Sem cartão, sem borda, sem
   sombra: como a banda e o filme são a MESMA cor, não existe mais caixa
   — é só a marca, grande.
   MOTIVO: a entrada estava pequena e vazia.
   CONSEQUÊNCIA ACEITA POR ELE: o arco-íris sai desta banda enquanto o
   filme está ligado (continua nas outras, e volta aqui se ele trocar
   para o selo em camadas). A escolha dele não é apagada — fica gravada
   no #ajustes e volta sozinha. */
.abertura-filme{
  position:relative;
  /* De ponta a ponta no celular: a banda tem padding-inline var(--gut),
     e a margem negativa devolve essa sobra para o filme. No computador
     o limite é a altura, não a largura — quadrado de 1400px não cabe. */
  /* 66vh, não mais: o filme + a folga + a deixa "role" + o respiro têm
     que caber na primeira tela junto. Medido: a 78vh o "role" caía
     logo abaixo da dobra num 1280x900 — o mesmo vazio que ele
     fotografou, só que pior, porque some. */
  width:min(calc(100% + var(--gut) * 2), min(66vh, 860px));
  margin-inline:calc(var(--gut) * -1);
  max-width:calc(100% + var(--gut) * 2);
  aspect-ratio:1/1; flex:none;
  overflow:clip;                 /* clip, não hidden: hidden cria container de rolagem */
}
/* ── O FIM DO FILME ──────────────────────────────────────────────
   Quando o filme acaba, o navegador descarta o quadro decodificado e
   pinta a área de PRETO (medido em 15/09/2026: [211,196,189] durante,
   [0,0,0] depois). Então no fim o vídeo sai de cena e entra o pôster,
   que é o mesmo último quadro — a logo pronta — como imagem.
   O --filme-fim é escrito pelo abertura.js.                          */
.abertura-filme[data-fim="sim"]{
  background-image:var(--filme-fim);
  background-size:cover; background-position:center;
}
.abertura-filme[data-fim="sim"] video{ opacity:0 }

.abertura-filme video{
  display:block; width:100%; height:100%; object-fit:cover;
  background-color:var(--filme-chapa, #FBF9F5);
}

/* A banda vira o creme do filme — é isso que faz a moldura desaparecer.
   A pintura de fundo (degradê/arco-íris) é suspensa AQUI, e só aqui,
   enquanto o filme está ligado. */
.abertura[data-abertura="filme"]{
  background-color:var(--filme-chapa, #FBF9F5);
  background-image:none;
  gap:clamp(10px, 2vh, 22px);
  padding-block:clamp(14px, 2.4vh, 34px);
}
/* A sobra vertical não fica toda embaixo da logo: o filme fica no meio e
   a deixa "role" desce para a beirada. Era o vazio que ele fotografou. */
.abertura[data-abertura="filme"] .abertura-filme{ margin-block:auto }
.abertura[data-abertura="filme"] .abertura-desce{ margin-top:0 }
/* Ele apagou a frase de abertura. Parágrafo vazio não é conteúdo: vira um
   fantasma de altura zero que o efeito de cascata deixa com opacidade 0 e
   ainda ocupa um passo da animação. Vazio, sai da página — e volta sozinho
   no instante em que ele escrever alguma coisa no Estúdio. */
.abertura-fala:empty{ display:none }

/* As duas aberturas nunca aparecem juntas. O atributo mora no HTML
   (não é escrito por script), então o estado sem JS já é o certo. */
.abertura[data-abertura="filme"] .selo-cena{ display:none }
.abertura:not([data-abertura="filme"]) .abertura-filme{ display:none }

/* O filme espera um toque quando o navegador recusou tocar sozinho.
   Sem botão e sem nada escrito por cima da marca — só o cursor muda,
   e a chapa inteira aceita o toque. Decisão do dono, 15/09/2026. */
.abertura-filme[data-toque="sim"]{ cursor:pointer }

/* O botão de tocar saiu da página em 15/09/2026. As regras ficam para
   modelos antigos que ainda tenham o elemento; nada o acende hoje. */
.filme-tocar{
  /* Fora da chapa, não em cima dela: dentro do quadrado ele caía sobre
     "brinquedos e revistas infantis" e cobria a assinatura da marca. */
  display:none; align-items:center; gap:7px; margin:0;
  border:2px solid color-mix(in oklab, var(--sobre, var(--tinta)) 30%, transparent);
  background:transparent; color:var(--sobre, var(--tinta));
  cursor:pointer; border-radius:999px; padding:8px 15px; min-height:38px;
  font-family:"DM Mono",ui-monospace,monospace; font-weight:500;
  font-size:11px; letter-spacing:.08em; text-transform:uppercase; line-height:1;
}
.filme-tocar:hover{ background:color-mix(in oklab, currentColor 10%, transparent) }
.abertura[data-tocar="sim"] .filme-tocar{ display:inline-flex }
.filme-tocar::before{ content:"▶"; font-size:9px }

/* Quando a página rola, o filme encolhe junto com o resto — o mesmo
   gesto que a cena em camadas já fazia. Reaproveita ab-recolhe. */
@media all /* era prefers-reduced-motion: quem manda é o botão Cinema */{
  @supports (animation-timeline: view()){
    [data-cinema="sim"] .abertura .abertura-filme{
      animation:ab-recolhe linear both;
      animation-timeline:view(); animation-range:exit 0% exit 100%;
    }
  }
}

/* ═══════════════════════════════════════════════════════════════
   PINTURA DO FUNDO — a banda não precisa ser cor chapada
   data-pintura="solido" (padrão) | "degrade" | "arcoiris"

   A variação nunca passa de 12% da cor do token. É de propósito:
   a guarda de contraste mede a cor do token, e um fundo que se
   afasta demais dela faria a medida mentir.
   ═══════════════════════════════════════════════════════════════ */
[data-pintura="degrade"]{
  background-image:linear-gradient(168deg,
    color-mix(in oklab, var(--cor-banda, transparent) 100%, #fff 0%) 0%,
    color-mix(in oklab, var(--cor-banda, transparent) 88%, var(--tinta) 12%) 100%);
}
[data-pintura="arcoiris"]{
  background-image:
    radial-gradient(120% 90% at 12% 0%,  color-mix(in oklab, var(--rosa)    22%, transparent), transparent 62%),
    radial-gradient(110% 85% at 88% 8%,  color-mix(in oklab, var(--azul)    20%, transparent), transparent 60%),
    radial-gradient(120% 95% at 50% 104%,color-mix(in oklab, var(--amarelo) 18%, transparent), transparent 58%),
    radial-gradient(100% 80% at 96% 92%, color-mix(in oklab, var(--verde)   16%, transparent), transparent 58%);
}

/* ═══════════════════════════════════════════════════════════════
   A LOGO COMO OBJETO · data-logo3d="sim"   (13/09/2026)

   Ligável no Estúdio, desligada por padrão. O estado base continua
   sendo a logo chapada e inteira — este bloco só ACRESCENTA
   profundidade e a saída do urso.

   As camadas são as mesmas quatro do selo, afastadas em Z. Não há
   modelo 3D nenhum: é a arte original em planos, que é o que dá
   profundidade de verdade sem redesenhar coisa alguma.
   ═══════════════════════════════════════════════════════════════ */
.selo-cena[data-logo3d="sim"]{
  perspective:1100px; perspective-origin:50% 42%;
}
.selo-cena[data-logo3d="sim"] > *{ transform-style:preserve-3d }
/* A profundidade vai na propriedade `translate`, NÃO em `transform`.
   Motivo medido: as animações de abertura terminam em transform:none e
   apagavam o translateZ. `translate` é propriedade independente — ela
   compõe com transform em vez de brigar com ele. */
.selo-cena[data-logo3d="sim"] .selo-placa{ translate:0 0 -26px }
.selo-cena[data-logo3d="sim"] .sc-cena  { translate:0 0   8px }
.selo-cena[data-logo3d="sim"] .sc-urso  { translate:0 0  34px }
.selo-cena[data-logo3d="sim"] .sc-l1    { translate:0 0  46px }
.selo-cena[data-logo3d="sim"] .sc-l2    { translate:0 0  52px }
.selo-cena[data-logo3d="sim"] .sc-as    { translate:0 0  58px }

/* o urso que desce e fica do lado do título.
   Ele mora numa COLUNA PRÓPRIA: quando o modo objeto está ligado, o
   herói abre um recuo à esquerda e o urso ocupa esse recuo. Sem o modo
   ligado, nem a coluna nem o urso existem — a página fica como está
   publicada hoje. */
.urso-trilho{
  position:absolute; left:0; top:0; bottom:0; z-index:3;
  pointer-events:none; width:clamp(78px,10.5vw,168px);
  display:flex; justify-content:center;
}
/* sticky: ele desce até o título e FICA lá enquanto o herói passa —
   que é o "segurando os títulos" que o dono pediu. */
.urso-voa{
  position:sticky; align-self:flex-start;
  top:calc(var(--topo-alt, 0px) + clamp(16px,4vh,44px));
  margin-top:clamp(74px,13vh,150px);
  display:block; width:clamp(62px,9vw,132px); height:auto;
  opacity:0;                       /* só aparece no modo objeto */
  filter:drop-shadow(0 16px 22px rgba(0,0,0,.34));
}
[data-logo3d-pagina="sim"] .urso-voa{ opacity:1 }
[data-logo3d-pagina="sim"] .heroi .limite{
  padding-left:clamp(78px,10.5vw,168px);
}
/* No celular a coluna comeria metade da largura. Lá o urso senta no
   canto de cima, pequeno, e o título fica com a linha inteira. */
@media (max-width:760px){
  [data-logo3d-pagina="sim"] .heroi .limite{ padding-left:0 }
  .urso-trilho{ left:auto; right:0; bottom:auto; height:0; width:auto }
  .urso-voa{ position:static; margin:-8px 2vw 0 0; width:clamp(56px,17vw,96px) }
}

@media all /* era prefers-reduced-motion: quem manda é o botão Cinema */{
  @supports (animation-timeline: view()){
    /* a logo gira devagar enquanto a cena sobe */
    [data-cinema="sim"] .selo-cena[data-logo3d="sim"]{
      animation:logo-gira linear both;
      animation-timeline:view(); animation-range:entry 40% exit 100%;
    }
    /* o urso CAI: sai da marca, gira um pouco e desce */
    [data-cinema="sim"] .selo-cena[data-logo3d="sim"] .sc-urso{
      animation:urso-cai linear both;
      animation-timeline:view(); animation-range:exit 0% exit 92%;
    }
    /* e reaparece embaixo, do lado do título, no mesmo trecho */
    [data-cinema="sim"][data-logo3d-pagina="sim"] .urso-voa{
      animation:urso-pousa linear both;
      animation-timeline:view(); animation-range:entry 0% entry 70%;
    }
  }
}
@keyframes logo-gira{
  from{ transform:rotateY(-13deg) rotateX(5deg) }
  to  { transform:rotateY( 11deg) rotateX(-4deg) }
}
@keyframes urso-cai{
  0%  { transform:translate(0,0) rotate(0deg); opacity:1 }
  70% { transform:translate(-46%,118%) rotate(-14deg); opacity:1 }
  100%{ transform:translate(-62%,190%) rotate(-19deg); opacity:0 }
}
@keyframes urso-pousa{
  from{ transform:translateY(-58%) rotate(-19deg); opacity:0 }
  60% { transform:translateY(6%)  rotate(4deg);  opacity:1 }
  to  { transform:translateY(0)   rotate(0deg);  opacity:1 }
}
[data-cinema="nao"] .selo-cena[data-logo3d="sim"],
[data-cinema="nao"] .urso-voa{
  animation:none !important; transform:none !important;
}

/* ═══════════════════════════════════════════════════════════════
   CAMINHO ALTERNATIVO · data-fx-js="sim"          (13/09/2026)

   O atributo é escrito pelo efeitos.js e SÓ por ele. Se o script não
   rodar, nada aqui se aplica e a página continua inteira e parada —
   a regra do estado base legível vale igual nos dois caminhos.

   Mesmos keyframes de sempre. O que muda é quem conduz: em vez do
   animation-timeline do navegador, uma animação PAUSADA com atraso
   negativo, e o --p escrito a cada rolagem.
   ═══════════════════════════════════════════════════════════════ */
@media all /* era prefers-reduced-motion: quem manda é o botão Cinema */{
  /* animation-timeline:auto é obrigatório aqui. Num navegador que TEM
     a linha do tempo nativa (e onde a prova força este caminho), a
     regra nativa continua valendo para a propriedade que eu não
     declaro — e era ela que mandava, deixando o texto no quadro 0. */
  [data-fx-js="sim"][data-cinema="sim"] [data-fx]{
    animation-duration:1s; animation-timing-function:linear;
    animation-fill-mode:both; animation-play-state:paused;
    animation-delay:calc(var(--p, 0) * -1s);
    animation-timeline:auto;
  }
  [data-fx-js="sim"][data-cinema="sim"] [data-fx="sobe"]   { animation-name:fx-sobe }
  [data-fx-js="sim"][data-cinema="sim"] [data-fx="respira"]{ animation-name:fx-respira }
  [data-fx-js="sim"][data-cinema="sim"] [data-fx="chega"]  { animation-name:fx-chega }
  [data-fx-js="sim"][data-cinema="sim"] [data-fx="mascara"]{ animation-name:fx-mascara }
  [data-fx-js="sim"][data-cinema="sim"] [data-fx="foco"]   { animation-name:fx-foco }
  [data-fx-js="sim"][data-cinema="sim"] [data-fx="cortina"]{ animation-name:fx-cortina }
  [data-fx-js="sim"][data-cinema="sim"] [data-fx="desliza"]{ animation-name:fx-desliza }
  /* a cascata anima os FILHOS, cada um com o seu próprio --p */
  [data-fx-js="sim"][data-cinema="sim"] [data-fx="cascata"]{ animation-name:none }
  [data-fx-js="sim"][data-cinema="sim"] [data-fx="cascata"] > *{
    animation:fx-sobe 1s linear both paused; animation-timeline:auto;
    animation-delay:calc(var(--p, 0) * -1s);
    animation-timeline:auto;
  }

  /* as peças de nome próprio */
  [data-fx-js="sim"][data-cinema="sim"] .abertura .selo-cena{
    animation:ab-recolhe 1s linear both paused;
    animation-delay:calc(var(--p, 0) * -1s);
    animation-timeline:auto;
  }
  /* o filme encolhe igual à cena em camadas, no caminho sem linha do
     tempo nativa (iPhone, Firefox) */
  [data-fx-js="sim"][data-cinema="sim"] .abertura .abertura-filme{
    animation:ab-recolhe 1s linear both paused;
    animation-delay:calc(var(--p, 0) * -1s);
    animation-timeline:auto;
  }
  [data-fx-js="sim"][data-cinema="sim"] .selo-cena[data-logo3d="sim"]{
    animation:logo-gira 1s linear both paused;
    animation-delay:calc(var(--p, 0) * -1s);
    animation-timeline:auto;
  }
  [data-fx-js="sim"][data-cinema="sim"] .selo-cena[data-logo3d="sim"] .sc-urso{
    animation:urso-cai 1s linear both paused;
    animation-delay:calc(var(--p, 0) * -1s);
    animation-timeline:auto;
  }
  [data-fx-js="sim"][data-cinema="sim"][data-logo3d-pagina="sim"] .urso-voa{
    animation:urso-pousa 1s linear both paused;
    animation-delay:calc(var(--p, 0) * -1s);
    animation-timeline:auto;
  }
  [data-fx-js="sim"][data-cinema="sim"] .vit[data-360] .item-foto{
    animation:vit-gira 1s linear both paused;
    animation-delay:calc(var(--p, 0) * -1s);
    animation-timeline:auto;
  }
}
/* Cinema desligado continua desligando tudo, nos dois caminhos. */
[data-cinema="nao"] [data-fx],
[data-cinema="nao"] [data-fx="cascata"] > *{
  animation:none !important;
}
