/* Diorama V0 — "Meu Mundo": pequena ilha-maquete flutuando no universo
   Misturária, mesma linguagem cósmica de Perfis/Álbum/Árvore. Nunca um
   mapa técnico: profundidade em camadas, nada de grid de estratégia. */
.diorama-overlay {
  position: fixed;
  inset: 0;
  z-index: 42;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* V1.3 §4: menos "caixa de interface pousada sobre o Diorama", mais céu
   ao redor — mesma linguagem já usada em .barra-perfil-nome (texto
   pousado direto sobre a cena, legível pelo text-shadow, sem fundo
   sólido por trás). Título/descrição/Fechar continuam todos ali, só que
   mais leves. */
.diorama-cabecalho {
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin: 10px 12px 0;
  padding: 4px 2px;
}
.diorama-titulo {
  margin: 0;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: 0.2px;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.85), 0 0 18px rgba(120, 150, 255, 0.35);
}
.diorama-subtitulo {
  margin: 3px 0 0;
  font-size: 12px;
  opacity: 0.85;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.85);
}
.diorama-fechar {
  flex-shrink: 0;
  padding: 7px 13px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(10, 14, 26, 0.32);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--cor-texto);
  font-size: 12.5px;
  cursor: pointer;
  transition: transform 120ms ease, background 120ms ease;
}
.diorama-fechar:hover { transform: translateY(-1px); background: rgba(10, 14, 26, 0.5); }

/* ---- cena: céu cósmico (fundo-cosmico já cobre) + ilha flutuando ---- */
.diorama-cena {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  min-height: 0;
}

.diorama-ilha {
  position: relative;
  /* Mobile mantém a escala já validada (quase toda a largura útil, num
     teto pequeno). Tablet/desktop calibrados pra o mundo parecer algo pra
     OBSERVAR, não um ícone perdido no fundo cósmico — ver breakpoints
     abaixo. O teto em vh evita estourar a altura em janelas baixas. */
  width: min(94%, 480px, 80vh);
  aspect-ratio: 400 / 300;
  filter: drop-shadow(0 30px 40px rgba(0, 0, 0, 0.55));
  transition: filter 400ms ease, width 200ms ease;
}
.diorama-ilha-era-nova {
  animation: diorama-era-pulso 900ms ease;
}
.diorama-ilha-era-nova .diorama-mundo {
  filter: drop-shadow(0 0 18px rgba(255, 210, 110, 0.85));
}
@keyframes diorama-era-pulso {
  0% { transform: scale(1); }
  35% { transform: scale(1.035); }
  100% { transform: scale(1); }
}

/* ---- geografia: terreno-master é o palco visual principal (assets
   finais aprovados). Água e cobertura verde são camadas PNG derivadas da
   MESMA ilha por color-key sobre as referências aprovadas — nunca a
   imagem full-state inteira substituindo o terreno (ver relatório de
   entrega). Elas se sobrepõem em registro perfeito porque nascem do
   mesmo canvas/escala do terreno-master. Só a "roupa" (brilho da água,
   opacidade da grama) reage ao estado via data-nivel-* em .diorama-mundo. */
.diorama-mundo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.diorama-mundo-terreno,
.diorama-mundo-agua,
.diorama-mundo-agua-nascente,
.diorama-mundo-cachoeira,
.diorama-mundo-vegetacao,
.diorama-mundo-vegetacao-rala {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  user-select: none;
}
.diorama-mundo-terreno { z-index: 1; transition: filter 900ms ease; }
.diorama-mundo-agua-nascente { z-index: 2; opacity: 0; transition: opacity 900ms ease, filter 700ms ease, -webkit-mask-image 900ms ease, mask-image 900ms ease; }
.diorama-mundo-agua { z-index: 2; opacity: 0; transition: opacity 900ms ease, filter 700ms ease, -webkit-mask-image 900ms ease, mask-image 900ms ease; }
.diorama-mundo-vegetacao-rala { z-index: 3; opacity: 0; transition: opacity 1100ms ease, -webkit-mask-image 1100ms ease, mask-image 1100ms ease; }
.diorama-mundo-vegetacao { z-index: 3; opacity: 0; transition: opacity 1100ms ease, filter 1100ms ease; }

/* água: progressão FÍSICA (Round B) — não é só "quanto revela", é volume,
   largura, brilho e sensação de fluxo. Duas layers derivadas da MESMA
   arte canônica (agua-layer.png), registradas pixel a pixel:
   - agua-nascente.png = poça primordial + fio fino (N0/N1);
   - agua-layer.png    = sistema hídrico com largura/lago (N2..N4).
   O crossfade nascente->layer em N1->N2 é o único ponto onde a LARGURA
   muda de verdade. Brilho/saturação escalam por nível; a sensação de
   fluxo vem de .diorama-mundo-agua-fluxo (shimmer CSS, sem asset).
   Centro das máscaras = ANCHORS.nascente (40%, 28%). */
.diorama-mundo-agua-nascente {
  --raio-nasc: 6%;
  mask-image: radial-gradient(circle at 40% 28%, #000 var(--raio-nasc), transparent calc(var(--raio-nasc) + 8%));
  -webkit-mask-image: radial-gradient(circle at 40% 28%, #000 var(--raio-nasc), transparent calc(var(--raio-nasc) + 8%));
}
.diorama-mundo[data-nivel-agua='0'] .diorama-mundo-agua-nascente { opacity: 0.92; --raio-nasc: 5%; filter: saturate(0.7) brightness(0.94); }
.diorama-mundo[data-nivel-agua='1'] .diorama-mundo-agua-nascente { opacity: 1; --raio-nasc: 17%; filter: saturate(0.95) brightness(1); }
.diorama-mundo[data-nivel-agua='2'] .diorama-mundo-agua-nascente { opacity: 0.22; --raio-nasc: 22%; }

.diorama-mundo-agua {
  --raio-agua: 30%;
  mask-image: radial-gradient(circle at 40% 28%, #000 var(--raio-agua), transparent calc(var(--raio-agua) + 10%));
  -webkit-mask-image: radial-gradient(circle at 40% 28%, #000 var(--raio-agua), transparent calc(var(--raio-agua) + 10%));
  filter: brightness(calc(1.05 + var(--vitalidade, 0) * 0.006)) saturate(1.05);
}
.diorama-mundo[data-nivel-agua='2'] .diorama-mundo-agua { opacity: 1; --raio-agua: 30%; filter: brightness(calc(1.06 + var(--vitalidade, 0) * 0.006)) saturate(1.07); }
.diorama-mundo[data-nivel-agua='3'] .diorama-mundo-agua { opacity: 1; --raio-agua: 46%; filter: brightness(calc(1.14 + var(--vitalidade, 0) * 0.006)) saturate(1.24); }
.diorama-mundo[data-nivel-agua='4'] .diorama-mundo-agua { opacity: 1; --raio-agua: 100%; filter: brightness(calc(1.2 + var(--vitalidade, 0) * 0.006)) saturate(1.34); }
.mundo-pulso-agua .diorama-mundo-agua,
.mundo-pulso-agua .diorama-mundo-agua-nascente { animation: diorama-agua-pulso 700ms ease; }
@keyframes diorama-agua-pulso {
  0%, 100% { filter: brightness(1.1) saturate(1.1); }
  45% { filter: brightness(1.55) saturate(1.6); }
}

/* sensação de fluxo: brilho translúcido correndo na diagonal do curso,
   mascarado pelo mesmo raio da água. Quanto mais alto o nível, mais
   rápido corre (rio caudaloso). Sem asset — só CSS. Some com
   prefers-reduced-motion. */
.diorama-mundo-agua-fluxo {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  --raio-fluxo: 30%;
  background: repeating-linear-gradient(118deg,
    transparent 0 22px,
    rgba(233, 249, 255, 0.16) 22px 30px,
    transparent 30px 52px);
  mix-blend-mode: soft-light;
  /* dois masks compostos: a SILHUETA da água (agua-layer.png) ∩ o raio
     revelado por nível — o shimmer só aparece EM CIMA da água revelada,
     nunca sobre terra, rocha ou o fundo cósmico. */
  mask-image:
    url("../assets/diorama/agua-layer.png"),
    radial-gradient(circle at 40% 28%, #000 var(--raio-fluxo), transparent calc(var(--raio-fluxo) + 12%));
  mask-composite: intersect;
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: contain;
  -webkit-mask-image:
    url("../assets/diorama/agua-layer.png"),
    radial-gradient(circle at 40% 28%, #000 var(--raio-fluxo), transparent calc(var(--raio-fluxo) + 12%));
  -webkit-mask-composite: source-in;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center;
  -webkit-mask-size: contain;
  animation: diorama-agua-fluxo 6s linear infinite;
  transition: opacity 900ms ease, -webkit-mask-image 900ms ease, mask-image 900ms ease;
}
@keyframes diorama-agua-fluxo { to { background-position: 140px 46px; } }
.diorama-mundo[data-nivel-agua='2'] .diorama-mundo-agua-fluxo { opacity: 0.5; --raio-fluxo: 30%; animation-duration: 7s; }
.diorama-mundo[data-nivel-agua='3'] .diorama-mundo-agua-fluxo { opacity: 0.72; --raio-fluxo: 62%; animation-duration: 4.4s; }
.diorama-mundo[data-nivel-agua='4'] .diorama-mundo-agua-fluxo { opacity: 0.9; --raio-fluxo: 100%; animation-duration: 2.8s; }
@media (prefers-reduced-motion: reduce) { .diorama-mundo-agua-fluxo { animation: none; } }

/* cachoeira forte (Round B, passo 4) — layer isolada derivada da MESMA
   agua-layer.png canônica (só a queda: lip -> base, corpo alargado,
   espuma reforçada). Registrada pixel a pixel; ponto de saída na borda
   frontal idêntico ao canônico. Aparece só quando o rio já é cheio:
   N3 = cascata começando (fraca), N4 = queda caudalosa (cheia). É o que
   dá o salto perceptível N3 -> N4. z-index 2 = acima do terreno, abaixo
   do caminho (z8) e de todos os objetos (z6+). */
.diorama-mundo-cachoeira {
  z-index: 2;
  opacity: 0;
  /* origem = centro/base da própria queda (borda_cachoeira ≈ 63%, 84%) —
     escalar a layer encolhe o filete NO LUGAR, sem mexer no ponto de
     saída da borda frontal. */
  transform-origin: 63% 84%;
  transform: scaleX(0.62) scaleY(0.8);
  transition: opacity 1000ms ease, filter 900ms ease, transform 900ms ease;
}
.diorama-mundo[data-nivel-agua='3'] .diorama-mundo-cachoeira {
  opacity: 0.5;
  transform: scaleX(0.66) scaleY(0.82);
  filter: brightness(0.9) saturate(0.82);
}
.diorama-mundo[data-nivel-agua='4'] .diorama-mundo-cachoeira {
  opacity: 1;
  transform: scaleX(1) scaleY(1);
  filter: brightness(calc(1.06 + var(--vitalidade, 0) * 0.005)) saturate(1.12);
}
.mundo-pulso-agua .diorama-mundo-cachoeira { animation: diorama-agua-pulso 700ms ease; }

/* névoa/spray na base da queda — só CSS (radial-gradient), respiro leve.
   Elipse contida bem dentro da ponta frontal da ilha: não vaza para o
   fundo cósmico (stops transparentes muito antes das bordas do palco).
   Some com prefers-reduced-motion. */
.diorama-mundo-cachoeira-mist {
  position: absolute;
  left: 47%;
  top: 78%;
  width: 32%;
  height: 16%;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 45%,
    rgba(240, 250, 255, 0.6) 0%,
    rgba(232, 247, 255, 0.28) 34%,
    rgba(224, 244, 255, 0.08) 60%,
    transparent 78%);
  filter: blur(3px);
  transition: opacity 1000ms ease;
  animation: diorama-mist-respiro 5.5s ease-in-out infinite;
}
@keyframes diorama-mist-respiro {
  0%, 100% { transform: translateY(2%) scale(0.96); opacity: var(--mist-op, 0); }
  50% { transform: translateY(-4%) scale(1.06); opacity: calc(var(--mist-op, 0) * 1.25); }
}
.diorama-mundo[data-nivel-agua='3'] .diorama-mundo-cachoeira-mist { --mist-op: 0.2; opacity: 0.2; }
.diorama-mundo[data-nivel-agua='4'] .diorama-mundo-cachoeira-mist { --mist-op: 0.52; opacity: 0.52; }
@media (prefers-reduced-motion: reduce) {
  .diorama-mundo-cachoeira { animation: none; }
  .diorama-mundo-cachoeira-mist { animation: none; }
}

/* cobertura verde: progressão FÍSICA de densidade (Round B) —
   N0 sem cobertura -> N1 tufos/rala -> N2 cobertura baixa -> N3 cheia ->
   N4 mais volumosa/viva. Duas layers derivadas da MESMA arte canônica
   (vegetacao-layer.png), footprint alfa IDÊNTICO (dois campos, furos das
   rochas/leito — nunca cobre monte/arco/água):
   - vegetacao-rala.png = tufos esparsos com solo aparente (N1, some em N2);
   - vegetacao-layer.png = grama cheia (N2..N4).
   z-index 3: SEMPRE abaixo do caminho (z8), da ponte (z12) e de todos os
   objetos (z6+) — a grama nunca "engole" oficina/casa/ponte/etc, no pior
   caso vira gramado atrás deles. "Viva" no N4 é só filtro/respiro CSS
   (sem asset). */
.diorama-mundo-vegetacao-rala,
.diorama-mundo-vegetacao {
  --raio-grama: 0%;
  /* microavanço de vitalidade (V1.2.1): teto 6% no raio já liberado. */
  --raio-grama-efetivo: calc(var(--raio-grama) + min(var(--vitalidade, 0) * 0.3%, 6%));
  mask-image: radial-gradient(circle at 48% 52%, #000 var(--raio-grama-efetivo), transparent calc(var(--raio-grama-efetivo) + 18%));
  -webkit-mask-image: radial-gradient(circle at 48% 52%, #000 var(--raio-grama-efetivo), transparent calc(var(--raio-grama-efetivo) + 18%));
}

/* N1: só a rala. N2: crossfade rala->cheia. N3+: só a cheia. */
.diorama-mundo[data-nivel-vegetacao='1'] .diorama-mundo-vegetacao-rala { opacity: 1; --raio-grama: 24%; }
.diorama-mundo[data-nivel-vegetacao='2'] .diorama-mundo-vegetacao-rala { opacity: 0.35; --raio-grama: 42%; }

.diorama-mundo[data-nivel-vegetacao='2'] .diorama-mundo-vegetacao { opacity: 0.7; --raio-grama: 42%; filter: brightness(0.97); }
.diorama-mundo[data-nivel-vegetacao='3'] .diorama-mundo-vegetacao { opacity: 1; --raio-grama: 80%; filter: saturate(1.05); }
.diorama-mundo[data-nivel-vegetacao='4'] .diorama-mundo-vegetacao {
  opacity: 1;
  --raio-grama: 88%;
  filter: saturate(1.12) brightness(1.03) drop-shadow(0 1px 1px rgba(0, 0, 0, 0.22));
  animation: diorama-grama-viva 7.5s ease-in-out infinite;
}
@keyframes diorama-grama-viva {
  0%, 100% { filter: saturate(1.12) brightness(1.03) drop-shadow(0 1px 1px rgba(0, 0, 0, 0.22)); }
  50% { filter: saturate(1.2) brightness(1.06) drop-shadow(0 1px 2px rgba(0, 0, 0, 0.26)); }
}
.mundo-pulso-vegetacao .diorama-mundo-vegetacao,
.mundo-pulso-vegetacao .diorama-mundo-vegetacao-rala { animation: diorama-grama-pulso 900ms ease; }
@keyframes diorama-grama-pulso {
  0%, 100% { filter: brightness(1); }
  45% { filter: brightness(1.35) saturate(1.3); }
}
@media (prefers-reduced-motion: reduce) {
  .diorama-mundo[data-nivel-vegetacao='4'] .diorama-mundo-vegetacao { animation: none; }
}

/* caminho: só existe visualmente a partir do nível de civilização que o
   justifica — "se desenha" (stroke reveal), nunca aparece pronto. A
   ponte do kit aprovado ficou fora desta rodada (vem com rio/margem
   colados, sem versão bridge-only ainda — ver relatório de entrega). */
.diorama-mundo-caminho {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 8;
  pointer-events: none;
}
.geo-caminho { transition: stroke-dashoffset 1100ms ease; opacity: 0.85; }
.mundo-tem-caminho .geo-caminho { stroke-dashoffset: 0; }

/* cristal/energia discreta perto da nascente — já existe desde o Mundo
   Primordial (não deve parecer vazio), pulso bem sutil. */
.diorama-mundo-cristal {
  position: absolute;
  left: 39%;
  top: 24%;
  width: 5%;
  aspect-ratio: 1;
  z-index: 4;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(234, 249, 255, 0.9), rgba(127, 212, 230, 0) 70%);
  animation: diorama-cristal-respiro 4.2s ease-in-out infinite;
  pointer-events: none;
}
@keyframes diorama-cristal-respiro {
  0%, 100% { opacity: 0.7; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.2); }
}

/* terreno: agora muda pixels de verdade a cada nível (auditoria V1.2 §4)
   — sem asset novo, só contraste/saturação crescentes na MESMA imagem,
   um brilho mineral discreto perto de uma formação rochosa real, e
   poeira leve nos níveis mais altos. Nunca troca a geografia. */
.diorama-mundo[data-nivel-terreno='1'] .diorama-mundo-terreno { filter: contrast(1.05) saturate(1.04); }
.diorama-mundo[data-nivel-terreno='2'] .diorama-mundo-terreno { filter: contrast(1.1) saturate(1.09); }
.diorama-mundo[data-nivel-terreno='3'] .diorama-mundo-terreno { filter: contrast(1.16) saturate(1.14); }
.diorama-mundo[data-nivel-terreno='4'] .diorama-mundo-terreno { filter: contrast(1.22) saturate(1.2); }
.mundo-pulso-terreno .diorama-mundo-terreno { animation: diorama-terreno-pulso 700ms ease; }
@keyframes diorama-terreno-pulso {
  0%, 100% { filter: brightness(1); }
  45% { filter: brightness(1.25) contrast(1.2); }
}

/* brilho mineral: nasce perto de uma rocha real do terreno-master (canto
   esquerdo), só a partir do nível 2 — "enriquecimento visual de bordas". */
.diorama-mundo-terreno-brilho {
  position: absolute;
  left: 15%;
  top: 44%;
  width: 4%;
  aspect-ratio: 1;
  z-index: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 226, 170, 0.85), rgba(255, 200, 120, 0) 70%);
  opacity: 0;
  transition: opacity 900ms ease;
  pointer-events: none;
}
.diorama-mundo[data-nivel-terreno='2'] .diorama-mundo-terreno-brilho,
.diorama-mundo[data-nivel-terreno='3'] .diorama-mundo-terreno-brilho,
.diorama-mundo[data-nivel-terreno='4'] .diorama-mundo-terreno-brilho {
  opacity: calc(0.5 + var(--vitalidade, 0) * 0.015);
  animation: diorama-cristal-respiro 5s ease-in-out infinite;
}

/* poeira/partículas leves do solo — só nos níveis mais altos de terreno,
   intensidade acompanha a vitalidade (nunca cria objeto novo, só
   intensifica o que o nível de terreno já liberou). */
.diorama-mundo-terreno-poeira {
  position: absolute;
  inset: 0;
  z-index: 5;
  opacity: 0;
  pointer-events: none;
  transition: opacity 900ms ease;
}
.diorama-mundo[data-nivel-terreno='3'] .diorama-mundo-terreno-poeira,
.diorama-mundo[data-nivel-terreno='4'] .diorama-mundo-terreno-poeira {
  opacity: calc(0.35 + var(--vitalidade, 0) * 0.02);
}
.diorama-mundo-terreno-poeira span {
  position: absolute;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: rgba(255, 224, 180, 0.8);
  animation: diorama-poeira-flutua 7s ease-in-out infinite;
}
.diorama-mundo-terreno-poeira span:nth-child(1) { left: 20%; top: 55%; animation-delay: 0s; }
.diorama-mundo-terreno-poeira span:nth-child(2) { left: 68%; top: 48%; animation-delay: 2.3s; }
.diorama-mundo-terreno-poeira span:nth-child(3) { left: 40%; top: 62%; animation-delay: 4.6s; }
@keyframes diorama-poeira-flutua {
  0%, 100% { transform: translate(0, 0); opacity: 0; }
  15% { opacity: 1; }
  50% { transform: translate(6px, -10px); opacity: 0.7; }
  85% { opacity: 0; }
}

/* elementos primários — fogo e ar (auditoria V1.2 §1/§2): manifestação
   mínima e PRÓPRIA, nunca mais dependente do fallback "terreno". Sempre
   presentes desde que o item-base exista no save (checado por
   src/ui/diorama.js via elementosPrimarios, não assumido aqui). */
.diorama-mundo-fogo {
  position: absolute;
  left: 24%;
  top: 41%;
  width: 2.2%;
  aspect-ratio: 1;
  z-index: 2;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 176, 90, 0.95), rgba(255, 100, 40, 0.5) 55%, rgba(255, 80, 20, 0) 75%);
  opacity: 0;
  filter: blur(0.3px);
  transition: opacity 700ms ease;
  pointer-events: none;
}
.mundo-tem-fogo .diorama-mundo-fogo {
  opacity: calc(0.75 + var(--vitalidade, 0) * 0.01);
  animation: diorama-fogo-brasa 2.6s ease-in-out infinite;
}
@keyframes diorama-fogo-brasa {
  0%, 100% { transform: scale(1); filter: brightness(1); }
  50% { transform: scale(1.18); filter: brightness(1.3); }
}

.diorama-mundo-ar {
  position: absolute;
  inset: 0;
  z-index: 6;
  opacity: 0;
  pointer-events: none;
  transition: opacity 700ms ease;
}
.mundo-tem-ar .diorama-mundo-ar { opacity: calc(0.5 + var(--vitalidade, 0) * 0.02); }
.diorama-mundo-ar span {
  position: absolute;
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.65);
  animation: diorama-ar-vento 9s linear infinite;
}
.diorama-mundo-ar span:nth-child(1) { left: 8%; top: 20%; animation-delay: 0s; }
.diorama-mundo-ar span:nth-child(2) { left: 5%; top: 33%; animation-delay: 3s; }
.diorama-mundo-ar span:nth-child(3) { left: 10%; top: 12%; animation-delay: 6s; }
@keyframes diorama-ar-vento {
  0% { transform: translateX(0); opacity: 0; }
  10% { opacity: 0.8; }
  90% { opacity: 0.4; }
  100% { transform: translateX(85vw); opacity: 0; }
}

/* vitalidade (V1.2.1): cada tick alterna QUAL coisa já existente pulsa —
   nunca sempre a mesma, nunca cria nada novo. Reações bem discretas
   (nunca competem com um marco semântico: sem legenda, sem som). */
.mundo-pulso-vitalidade-agua .diorama-mundo-agua { animation: diorama-vitalidade-agua 420ms ease; }
@keyframes diorama-vitalidade-agua {
  /* sem 0%/100%: o navegador usa o filtro "de base" (já tiered pelo
     nível semântico da água) como ponto de partida/chegada — só o meio
     do pulso sobe o brilho, nunca reseta o tier atual. */
  50% { filter: brightness(1.18) saturate(1.15); }
}
.mundo-pulso-vitalidade-ar .diorama-mundo-ar { animation: diorama-vitalidade-ar 420ms ease; }
@keyframes diorama-vitalidade-ar {
  0%, 100% { opacity: calc(0.5 + var(--vitalidade, 0) * 0.02); }
  50% { opacity: calc(0.85 + var(--vitalidade, 0) * 0.02); }
}
.mundo-pulso-vitalidade-terra .diorama-mundo-terreno-poeira { animation: diorama-vitalidade-terra 420ms ease; }
/* brilho mineral já respira continuamente (diorama-cristal-respiro) —
   soma a animação em vez de substituir, senão o pulso corta o respiro. */
.mundo-pulso-vitalidade-terra[data-nivel-terreno='2'] .diorama-mundo-terreno-brilho,
.mundo-pulso-vitalidade-terra[data-nivel-terreno='3'] .diorama-mundo-terreno-brilho,
.mundo-pulso-vitalidade-terra[data-nivel-terreno='4'] .diorama-mundo-terreno-brilho {
  animation: diorama-cristal-respiro 5s ease-in-out infinite, diorama-vitalidade-terra 420ms ease;
}
@keyframes diorama-vitalidade-terra {
  50% { filter: brightness(1.4); }
}
/* ember já respira continuamente (diorama-fogo-brasa) — mesma lógica. */
.mundo-tem-fogo.mundo-pulso-vitalidade-fogo .diorama-mundo-fogo {
  animation: diorama-fogo-brasa 2.6s ease-in-out infinite, diorama-vitalidade-fogo 420ms ease;
}
@keyframes diorama-vitalidade-fogo {
  50% { transform: scale(1.35); filter: brightness(1.5); }
}
.mundo-pulso-vitalidade-cosmico { animation: diorama-vitalidade-cosmico 420ms ease; }
@keyframes diorama-vitalidade-cosmico {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.05); }
}

/* ---- objetos: cada marco planta um elemento numa âncora fixa (x/y/z
   vêm de ANCHORS em diorama-mundo.js) — nunca uma célula de grid/slot de
   inventário; a posição é do MUNDO, não de uma lista. ---- */
.diorama-objetos {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.diorama-objeto {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(15% * var(--diorama-escala, 1));
  /* zera o padding default do user-agent para <button> (1px 6px): com
     box-sizing border-box + <img width:100%>, esse padding encolhia a
     arte 12px de largura em TODO objeto (altura cai junto via height:auto),
     com impacto proporcionalmente maior nos assets pequenos. A largura
     renderizada tem que ser exatamente widthPct = 15% * escala. */
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  pointer-events: auto;
  container-type: inline-size;
}
/* ponto de contato com o solo (§9 do briefing): "de chão" fica preso pela
   base no anchor (o pé encosta no mundo); "flutuante" fica centrado nele.
   Vem só do registro ELEMENTOS/diorama-mundo.js — nunca um offset de asset. */
.diorama-objeto-base { transform: translate(-50%, -100%); }
.diorama-objeto-centro { transform: translate(-50%, -50%); }
.diorama-objeto:focus-visible { outline: 2px solid #fff; outline-offset: 4px; border-radius: 8px; }
.diorama-objeto-img {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.45));
  transition: transform 220ms ease;
}
.diorama-objeto-icone {
  font-size: clamp(16px, calc(9cqw * var(--diorama-escala, 1)), 30px);
  line-height: 1;
  filter: drop-shadow(0 3px 5px rgba(0, 0, 0, 0.55));
  transition: transform 220ms ease;
}
.diorama-objeto:hover .diorama-objeto-img,
.diorama-objeto:hover .diorama-objeto-icone { transform: scale(1.08); }
.diorama-objeto-toque .diorama-objeto-img,
.diorama-objeto-toque .diorama-objeto-icone { transform: scale(1.18); }

/* transformações de entrada por tipo (§5 — "Grow-like"): cada objeto novo
   nasce do próprio mundo, nunca só aparece com display:block. Aplicadas
   tanto em imagem quanto em emoji-placeholder. */
.diorama-objeto-anim-nasce-do-solo .diorama-objeto-img,
.diorama-objeto-anim-nasce-do-solo .diorama-objeto-icone {
  animation: diorama-nasce-do-solo 640ms ease; transform-origin: 50% 100%;
}
@keyframes diorama-nasce-do-solo {
  0% { transform: scaleY(0.05) scaleX(0.7); opacity: 0; }
  60% { transform: scaleY(1.15) scaleX(1.02); opacity: 1; }
  100% { transform: scaleY(1) scaleX(1); opacity: 1; }
}
.diorama-objeto-anim-cresce .diorama-objeto-img,
.diorama-objeto-anim-cresce .diorama-objeto-icone {
  animation: diorama-cresce 640ms cubic-bezier(.34,1.56,.64,1); transform-origin: 50% 100%;
}
@keyframes diorama-cresce {
  0% { transform: scale(0.35) translateY(6%); opacity: 0.2; filter: blur(2px); }
  70% { filter: blur(0); }
  100% { transform: scale(1) translateY(0); opacity: 1; filter: blur(0); }
}
.diorama-objeto-anim-entra-voando .diorama-objeto-img,
.diorama-objeto-anim-entra-voando .diorama-objeto-icone { animation: diorama-entra-voando 620ms ease; }
@keyframes diorama-entra-voando {
  0% { transform: translate(-26px, -16px) scale(0.6); opacity: 0; }
  100% { transform: translate(0, 0) scale(1); opacity: 1; }
}
.diorama-objeto-anim-entra-andando .diorama-objeto-img,
.diorama-objeto-anim-entra-andando .diorama-objeto-icone { animation: diorama-entra-andando 620ms ease; }
@keyframes diorama-entra-andando {
  0% { transform: translateX(22px) scale(0.7); opacity: 0; }
  100% { transform: translateX(0) scale(1); opacity: 1; }
}
.diorama-objeto-anim-acende .diorama-objeto-img,
.diorama-objeto-anim-acende .diorama-objeto-icone {
  animation: diorama-acende 620ms ease; transform-origin: 50% 100%;
}
@keyframes diorama-acende {
  0% { opacity: 0; transform: scale(0.55); filter: brightness(2.2) drop-shadow(0 0 12px rgba(255, 210, 110, 0.9)); }
  100% { opacity: 1; transform: scale(1); filter: brightness(1) drop-shadow(0 4px 6px rgba(0, 0, 0, 0.45)); }
}
.diorama-objeto-anim-monta .diorama-objeto-img,
.diorama-objeto-anim-monta .diorama-objeto-icone {
  animation: diorama-monta 720ms ease; transform-origin: 50% 100%;
}
@keyframes diorama-monta {
  0% { transform: translateY(10px) scale(0.6); opacity: 0; }
  55% { transform: translateY(-3px) scale(1.08); opacity: 1; }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}
.diorama-objeto-anim-aparece .diorama-objeto-img,
.diorama-objeto-anim-aparece .diorama-objeto-icone { animation: diorama-aparece 480ms ease; }
@keyframes diorama-aparece {
  0% { transform: scale(0.5); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}

/* portal/orbe de criações da IA — sinal discreto, nunca thresholds canônicos */
.diorama-ia-portal {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--cor-orbe-ia) 55%, transparent);
  background:
    radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.35), transparent 50%),
    color-mix(in srgb, var(--cor-orbe-ia) 30%, rgba(8, 13, 28, 0.7));
  box-shadow: 0 0 14px -2px color-mix(in srgb, var(--cor-orbe-ia) 60%, transparent);
  color: var(--cor-texto);
  font-size: 16px;
  cursor: pointer;
  animation: diorama-ia-respiro 3.4s ease-in-out infinite;
}
@keyframes diorama-ia-respiro {
  0%, 100% { opacity: 0.85; } 50% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .diorama-ia-portal { animation: none; }
}

.diorama-legenda {
  min-height: 18px;
  margin: 0;
  padding: 6px 16px max(10px, env(safe-area-inset-bottom));
  text-align: center;
  font-size: 12.5px;
  opacity: 0.9;
}

@media (prefers-reduced-motion: reduce) {
  .diorama-ilha-era-nova,
  .diorama-mundo-cristal,
  .mundo-pulso-agua .diorama-mundo-agua,
  .mundo-pulso-vegetacao .diorama-mundo-vegetacao,
  .diorama-objeto-anim-nasce-do-solo .diorama-objeto-img,
  .diorama-objeto-anim-nasce-do-solo .diorama-objeto-icone,
  .diorama-objeto-anim-cresce .diorama-objeto-img,
  .diorama-objeto-anim-cresce .diorama-objeto-icone,
  .diorama-objeto-anim-entra-voando .diorama-objeto-img,
  .diorama-objeto-anim-entra-voando .diorama-objeto-icone,
  .diorama-objeto-anim-entra-andando .diorama-objeto-img,
  .diorama-objeto-anim-entra-andando .diorama-objeto-icone,
  .diorama-objeto-anim-acende .diorama-objeto-img,
  .diorama-objeto-anim-acende .diorama-objeto-icone,
  .diorama-objeto-anim-monta .diorama-objeto-img,
  .diorama-objeto-anim-monta .diorama-objeto-icone,
  .diorama-objeto-anim-aparece .diorama-objeto-img,
  .diorama-objeto-anim-aparece .diorama-objeto-icone,
  .mundo-pulso-terreno .diorama-mundo-terreno,
  .diorama-mundo-terreno-brilho,
  .diorama-mundo-terreno-poeira span,
  .mundo-tem-fogo .diorama-mundo-fogo,
  .diorama-mundo-ar span,
  .mundo-pulso-vitalidade-agua .diorama-mundo-agua,
  .mundo-pulso-vitalidade-ar .diorama-mundo-ar,
  .mundo-pulso-vitalidade-terra .diorama-mundo-terreno-poeira,
  .mundo-pulso-vitalidade-terra .diorama-mundo-terreno-brilho,
  .mundo-pulso-vitalidade-fogo .diorama-mundo-fogo,
  .mundo-pulso-vitalidade-cosmico { animation: none; }
  .diorama-objeto-img, .diorama-objeto-icone, .diorama-ilha, .diorama-mundo-agua,
  .diorama-mundo-vegetacao, .diorama-mundo-terreno, .geo-caminho,
  .diorama-mundo-terreno-brilho, .diorama-mundo-terreno-poeira,
  .diorama-mundo-fogo, .diorama-mundo-ar { transition: none; }
  /* sem movimento, a poeira/vento ambiente vira decoração estática visível
     (nunca invisível) em vez de animar — mantém a manifestação mínima. */
  .diorama-mundo[data-nivel-terreno='3'] .diorama-mundo-terreno-poeira,
  .diorama-mundo[data-nivel-terreno='4'] .diorama-mundo-terreno-poeira { opacity: 0.45; }
  .diorama-mundo-terreno-poeira span, .diorama-mundo-ar span { opacity: 0.6; }
}

@media (min-width: 640px) {
  .diorama-cabecalho { margin: 14px 18px 0; }
  .diorama-titulo { font-size: 19px; }
  /* tablet (V1.3: "aumentar claramente"): protagonista de verdade — bem
     mais que a metade da largura útil, ainda com boa margem cósmica. */
  .diorama-ilha { width: min(72%, 700px, 80vh); }
}

@media (min-width: 1024px) {
  /* desktop/tablet horizontal: ~40-50% da largura útil do palco (nunca
     um ícone central) — mesmo centro visual, mesma geografia, só maior.
     Piso alto (580px) garante que tablets em paisagem (~1024-1200px de
     largura, onde 45vw sozinho ainda ficaria pequeno) também recebam uma
     ilha claramente grande; o teto (820px) evita exagero em telas
     ultra-largas; o teto em vh evita estourar a altura em janelas baixas. */
  .diorama-ilha { width: min(clamp(580px, 45vw, 820px), 80vh); }
}
