/* Boas Práticas na Receção — Ribeira Palace
   Paleta: preto/dourado, luxuoso, consistente com os assets fotográficos */

/* Tipografia oficial da marca (assets/logotipo_tipografia_ribeira_palace/tipografia) */
@font-face {
  font-family: 'Cardo';
  src: url('../assets/logotipo_tipografia_ribeira_palace/tipografia/Cardo-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Cardo';
  src: url('../assets/logotipo_tipografia_ribeira_palace/tipografia/Cardo-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Cardo';
  src: url('../assets/logotipo_tipografia_ribeira_palace/tipografia/Cardo-Italic.ttf') format('truetype');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

:root {
  --gold: #deb76f;
  --gold-bright: #deb76f;
  --gold-dark: #a6853f;
  --gold-gradient: linear-gradient(135deg, #f2e0b8 0%, #deb76f 40%, #b98f52 70%, #8a6a35 100%);
  --white-gradient: linear-gradient(180deg, #ffffff 0%, #f8f4ec 60%, #e9e1d1 100%);
  --ink: #0a0a0a;
  --card-bg: rgba(12, 11, 11, 0.90);
  --green: #3fae5c;
  --red: #d9534f;
  --white: #f5f1e8;
  --grey: #b9b4a8;
  --topbar-h: 64px;
  --font-serif: 'Cardo', Georgia, 'Times New Roman', serif;
  --font-sans: 'Segoe UI', system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  background: #000;
  color: var(--white);
  font-family: var(--font-sans);
  overflow: hidden;
}

button { font-family: inherit; cursor: pointer; }

/* ---------------- BARRA SUPERIOR ----------------
   Vive DENTRO do canvas de 1920x1080 (sobreposta ao topo da cena, tal como no
   guia de montagem), em vez de ser uma barra à parte fora do palco. Assim
   escala sempre junto com o resto e nunca sobra um "resto" de altura que
   desalinhe o palco em relação a um monitor 16:9 (era essa a causa das barras
   pretas laterais). Tamanhos em cqw = percentagem da largura do canvas, que
   por ter proporção fixa também corresponde sempre à mesma fração da altura. */

#app { position: absolute; inset: 0; overflow: hidden; }

/* Imagem real da barra (assets/layout_barra_superior) — preenche o canvas
   1920x1080 inteiro (só o topo tem conteúdo, o resto é transparente), tal
   como os templates de fala. Nunca desenhar um gradiente novo por cima. */
.topbar-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 499;
  pointer-events: none;
}

.stage-topbar {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 7.8%;
  z-index: 500;
  display: flex;
  align-items: center;
  padding: 0 1.9cqw;
  gap: 0.83cqw;
}

/* Sem barra superior no ecrã de entrada (ver updateTopbar em main.js). Usa o
   atributo HTML "hidden" (não uma classe) para ficar escondida logo na
   primeira pintura da página, antes mesmo do CSS/fontes carregarem — uma
   classe dependeria do style.css já estar aplicado e podia deixar passar um
   frame com a barra visível. Ao reaparecer, a classe "showing" faz um fade
   suave em vez de um "pop" instantâneo.
   [hidden] sozinho perderia para o ".stage-topbar{display:grid}" acima (regra
   de autor sempre vence a regra de baixa prioridade do browser para [hidden],
   mesmo com a mesma especificidade) — por isso repetimos a classe aqui para
   ganhar especificidade e garantir que display:none é mesmo aplicado. */
.topbar-frame[hidden],
.stage-topbar[hidden] {
  display: none;
}

.topbar-frame.showing,
.stage-topbar.showing {
  animation: topbarFadeIn 0.4s ease forwards;
}
@keyframes topbarFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Grupo central: só a barra de progresso (quando visível) — ocupa o espaço
   que sobra entre a marca à esquerda e os ícones à direita (flex:1) e
   centra o conteúdo dentro desse espaço, para ficar centrada em relação ao
   que sobra e não em relação à barra toda (que não é simétrica). */
.topbar-center {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}

.topbar-brand {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.8cqw;
  white-space: nowrap;
  overflow: hidden;
}
.topbar-brand-mark {
  display: flex;
  align-items: center;
  gap: 0.4cqw;
  flex-shrink: 0;
}
.brand-logo,
.capa-logo {
  object-fit: contain;
}
.brand-logo {
  height: 3.2cqw;
  width: 3.2cqw;
  min-height: 26px;
  min-width: 26px;
  flex-shrink: 0;
}
.brand-name {
  font-family: var(--font-serif);
  background: var(--white-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  letter-spacing: 0.18cqw;
  font-size: 1.15cqw;
  font-weight: bold;
  flex-shrink: 0;
  /* maiúsculas nesta fonte ficam com espaço de descendente por baixo por
     usar, sobrando vazio em baixo — desce um pouco para ficar centrado
     opticamente com o logótipo/ícones (que estão perfeitamente centrados). */
  position: relative;
  top: 0.12cqw;
}
.topbar-divider {
  width: 1px;
  height: 1.5cqw;
  background: rgba(255,255,255,0.25);
  flex-shrink: 0;
}
.brand-tagline {
  font-size: 0.8cqw;
  letter-spacing: 0.05cqw;
  text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topbar-progress {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.6cqw;
  width: 11cqw;
}
/* Ver nota em .stage-topbar[hidden]: uma regra de autor com display:flex
   ganha sempre ao [hidden] do browser, por isso repetimos aqui. */
.topbar-progress[hidden] {
  display: none;
}
.progress-track {
  flex: 1;
  height: 0.6cqw;
  background: rgba(255,255,255,0.12);
  border-radius: 4px;
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--gold-dark), var(--gold-bright));
  transition: width .4s ease;
}
.progress-label {
  font-size: 0.85cqw;
  font-weight: 700;
  color: var(--white);
  white-space: nowrap;
}

.topbar-icons { flex: 0 0 auto; display: flex; gap: 0.85cqw; }
.icon-btn {
  position: relative;
  background: linear-gradient(160deg, rgba(255,255,255,0.10), rgba(0,0,0,0.35) 60%);
  border: 1px solid rgba(212,175,106,0.55);
  color: var(--gold-bright);
  border-radius: 50%;
  width: 2.7cqw; height: 2.7cqw;
  min-width: 34px; min-height: 34px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  box-shadow: inset 0 0.06cqw 0 rgba(255,255,255,0.18), inset 0 -0.08cqw 0.2cqw rgba(0,0,0,0.5), 0 0.08cqw 0.25cqw rgba(0,0,0,0.5);
  transition: background .2s ease, color .2s ease, box-shadow .2s ease, transform .2s ease, border-color .2s ease;
}
.icon-btn svg { width: 68%; height: 68%; flex-shrink: 0; }
/* Ícone de idioma — usa as bandeiras já redondas (assets/bandeiras_idiomas/round/),
   por isso preenche o círculo por inteiro (100%), ao contrário dos svg's dos
   outros ícones (68%, com respiro à volta). */
#btnLang img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 50%; flex-shrink: 0; }
/* :hover só dentro de (hover: hover) and (pointer: fine) — em ecrãs
   táteis o browser aplica :hover ao tocar e só o larga ao tocar noutro
   sítio (não há "sair" com o dedo como há com o rato), o que deixava
   botões presos com o brilho de hover depois de um toque normal. Aplicado
   a todos os :hover deste ficheiro que davam esse problema. */
@media (hover: hover) and (pointer: fine) {
  .icon-btn:hover {
    background: linear-gradient(160deg, var(--gold-bright), var(--gold-dark) 85%);
    color: #1a1300;
    border-color: var(--gold-bright);
    transform: translateY(-0.1cqw) scale(1.08);
    box-shadow: inset 0 0.06cqw 0 rgba(255,255,255,0.4), 0 0 0.9cqw rgba(233,201,119,0.55), 0 0.15cqw 0.4cqw rgba(0,0,0,0.5);
  }
}

/* Respiração suave (só brilho/contorno, cor e tamanho do ícone não mudam)
   para chamar a atenção para o ecrã inteiro, até o utilizador clicar. */
@keyframes iconAttentionPulse {
  0%, 100% {
    border-color: rgba(212,175,106,0.55);
    box-shadow: inset 0 0.06cqw 0 rgba(255,255,255,0.18), inset 0 -0.08cqw 0.2cqw rgba(0,0,0,0.5), 0 0 0 rgba(233,201,119,0);
  }
  50% {
    border-color: var(--gold-bright);
    box-shadow: inset 0 0.06cqw 0 rgba(255,255,255,0.25), inset 0 -0.08cqw 0.2cqw rgba(0,0,0,0.4), 0 0 0.6cqw rgba(233,201,119,0.5);
  }
}
.icon-btn.pulse-attention { animation: iconAttentionPulse 2s ease-in-out infinite; }
@media (hover: hover) and (pointer: fine) {
  .icon-btn.pulse-attention:hover { animation: none; }
}
.icon-btn:active { transform: translateY(0) scale(0.97); }
.icon-btn.muted { color: var(--grey); border-color: rgba(255,255,255,0.25); }

/* ---------------- CONTEÚDO DO PALCO ---------------- */

.stage-content { position: absolute; inset: 0; }
.fade-in { position: absolute; inset: 0; animation: fadeIn .35s ease; }
/* Fade mais suave e lento, reservado para transições específicas (ver
   setScreenFade(html, slow) em main.js): fachada→receção, última fala do
   módulo→ecrã de resumo, ecrã de resumo→ecrã seguinte. */
.fade-in-slow { position: absolute; inset: 0; animation: fadeIn 1.4s ease; }
/* Ainda mais lento e suave — reservado à transição específica entre o
   último ecrã de boas práticas e o ecrã final do curso. */
.fade-in-final { position: absolute; inset: 0; animation: fadeIn 2.6s ease; }

.screen {
  position: absolute;
  inset: 0;
}

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* Palco — canvas de resolução fixa 1920x1080 (a mesma dos templates de fala),
   sempre desenhado ao mesmo "tamanho de projeto" e depois escalado inteiro
   (JS define left/top/transform:scale — ver layoutStage) para caber na janela.
   Por nunca mudar de layout, o formato fica sempre bloqueado: nada corta,
   nada deforma, em janela normal, maximizada ou em ecrã inteiro — só sobra
   letterbox preto quando a janela não é 16:9, como num leitor de vídeo. */
.stage {
  position: absolute;
  width: 1920px;
  height: 1080px;
  transform-origin: top left;
  background: #000;
  overflow: hidden;
  container-type: inline-size;
  box-shadow: 0 10px 50px rgba(0,0,0,0.6);
}

.bg-cover {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  width: 100%;
  height: 100%;
}

.bg-parallax {
  position: absolute;
  top: -2%; left: -2%; right: -2%; bottom: -2%;
  width: 104%; height: 104%;
  background-size: cover;
  background-position: center;
  will-change: transform;
}

/* A fachada (assets/fachada_hotel) é um ficheiro num formato muito maior que
   os restantes fundos, por isso aguenta uma margem/zoom maior sem perder
   qualidade (ver bgParallaxDiv() em main.js, que aplica esta classe só a ela).
   A imagem-fonte é exatamente 16:9 como o stage, por isso o zoom (nível de
   "cover") é sempre ditado pela LARGURA da caixa (110%, igual ao anterior).
   A altura fica propositadamente menor que a largura só para abrir uma folga
   vertical (a imagem passa a exceder a caixa em altura) que o
   background-position usa para descer o enquadramento — sem alterar o zoom. */
.bg-parallax.bg-zoom {
  top: 5%; bottom: 5%; height: 90%;
  left: -5%; right: -5%; width: 110%;
  background-position: center 95%;
}

.overlay-dark {
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,0.55);
}

/* ---------------- ECRÃ DE ENTRADA / FINAL ---------------- */

.hero-screen {
  position: absolute;
  inset: 0;
  display: flex; align-items: center; justify-content: center;
}

/* ---------------- ESCOLHA DE IDIOMA (dentro do ecrã de entrada) ----------------
   Fica sobreposta ao mesmo fundo/overlay da capa, centrada, enquanto o resto
   da capa (logo, título, barra de carregamento — ver .hero-screen#heroEntrada
   mais abaixo) está invisível e o fundo está parado no frame inicial (ver
   .entrada-bg). Ainda sem lógica de tradução por trás — só a UI, a ligar
   depois (ver renderEntrada em main.js). */

.idioma-wrap {
  position: absolute;
  left: 50%; top: 50%;
  z-index: 2;
  width: 46cqw;
  text-align: center;
  opacity: 0;
  animation: idiomaRise 1s cubic-bezier(.16,.8,.24,1) forwards;
  animation-delay: 0.6s;
  transition: opacity .5s ease;
}
/* Igual à heroRise, mas mantém sempre o translate(-50%,-50%) de centragem —
   a heroRise sobrescreve o transform inteiro (não soma), o que descentrava
   este elemento assim que a animação terminava. */
@keyframes idiomaRise {
  from { opacity: 0; transform: translate(-50%, calc(-50% + 18px)); filter: blur(4px); }
  to   { opacity: 1; transform: translate(-50%, -50%); filter: blur(0); }
}
.idioma-wrap.exit {
  /* anula a animação de entrada (que fica "presa" no fim por causa do
     forwards) para a transição de opacidade abaixo poder mesmo fazer o
     fade-out ao escolher o idioma. */
  animation: none;
  transform: translate(-50%, -50%);
  opacity: 0;
  pointer-events: none;
}
.idioma-prompt {
  display: flex;
  flex-direction: column;
  gap: 0.45cqw;
  margin: 0 0 1.6cqw;
}
.idioma-prompt-line {
  font-family: var(--font-sans);
  font-size: 1.2cqw;
  font-weight: 600;
  letter-spacing: 0.24cqw;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 0.15cqw 0.5cqw rgba(0,0,0,0.55);
}
.idioma-prompt-line:last-child {
  font-size: 0.98cqw;
  font-weight: 500;
  letter-spacing: 0.17cqw;
  color: rgba(255, 255, 255, 0.6);
  text-shadow: none;
}
.idioma-options {
  display: flex;
  justify-content: center;
  gap: 2.2cqw;
}
.idioma-option {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1cqw;
  width: 11.4cqw;
  padding: 1.3cqw 1cqw 1cqw;
  background: rgba(16, 14, 12, 0.65);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(233,201,119,0.25);
  border-radius: 12px;
  color: var(--white);
  cursor: pointer;
  overflow: hidden;
  transition: transform .22s cubic-bezier(.22,.61,.36,1), border-color .22s ease, background .22s ease, box-shadow .22s ease;
}
.idioma-flag {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4.4cqw;
  height: 2.9cqw;
  min-width: 48px;
  min-height: 32px;
  border-radius: 5px;
  overflow: hidden;
  background: rgba(0,0,0,0.3);
  box-shadow: 0 0.3cqw 0.8cqw rgba(0,0,0,0.4);
  transition: box-shadow .22s ease, transform .22s cubic-bezier(.22,.61,.36,1);
}
.idioma-flag img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.idioma-label {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 1.2cqw;
  letter-spacing: 0.02em;
  color: rgba(245, 241, 232, 0.85);
  transition: color .22s ease;
}
@media (hover: hover) and (pointer: fine) {
  .idioma-option:hover {
    transform: translateY(-0.25cqw);
    border-color: rgba(233,201,119,0.6);
    background: rgba(16, 14, 12, 0.65);
    box-shadow: 0 0.8cqw 1.8cqw rgba(0,0,0,0.35);
  }
  .idioma-option:hover .idioma-flag {
    transform: scale(1.06);
  }
  .idioma-option:hover .idioma-label { color: var(--white); }
}
.idioma-option:active { transform: translateY(0); }
.idioma-option:active .idioma-flag { transform: scale(0.98); }

/* Créditos encostados ao fundo do ecrã de escolha de idioma — irmão do
   .idioma-wrap (não filho: precisa de se ancorar ao fundo do ecrã todo, e
   o .idioma-wrap não tem altura própria, só a do seu conteúdo, por estar
   centrado verticalmente). Mesmo texto/estilo dos créditos do ecrã final
   (ver .final-footer-credit e final-credit-line1/final-credit-strong), mas
   sempre em português: este ecrã aparece ANTES da escolha de idioma, por
   isso não há t()/state.lang fiável para usar aqui (ver o bug do mesmo
   texto na capa, corrigido antes de se mudar para este ecrã). Desaparece
   junto com o .idioma-wrap (ver o seletor de irmão abaixo) assim que o
   idioma é escolhido. */
.idioma-credit {
  position: absolute;
  left: 50%;
  bottom: 1.7cqw;
  transform: translateX(-50%);
  z-index: 2;
  width: max-content;
  max-width: 90%;
  opacity: 0;
  animation: idiomaCreditRise 1s cubic-bezier(.16,.8,.24,1) forwards;
  animation-delay: 0.8s;
  transition: opacity .5s ease;
  text-align: center;
  font-size: 0.78cqw;
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: #ffffff;
}
@keyframes idiomaCreditRise {
  from { opacity: 0; transform: translate(-50%, 12px); filter: blur(4px); }
  to   { opacity: 1; transform: translate(-50%, 0); filter: blur(0); }
}
.idioma-wrap.exit ~ .idioma-credit {
  animation: none;
  opacity: 0;
  pointer-events: none;
}
.idioma-credit a {
  color: inherit;
  text-decoration: none;
  transition: color .15s ease;
}
@media (hover: hover) and (pointer: fine) {
  .idioma-credit a:hover { color: var(--gold-bright); text-decoration: underline; }
}

/* ---------------- CAPA DE ENTRADA (assets/layout_capa_entrada) ----------------
   O fundo fica parado no frame inicial (mesma escala do arranque do zoom out,
   ver heroKenBurns) enquanto só a escolha de idioma está visível; o resto da
   capa (logo, título, barra de carregamento) só aparece, e o zoom out do
   fundo só começa, depois de se escolher um idioma (ver .entrada-bg.zooming e
   .hero-screen#heroEntrada.entrada-anim, ligados em renderEntrada). Composição
   editorial: bloco de marca ancorado a ~42% da altura (não centrado a
   direito) e barra de carregamento com percentagem fixada ao fundo do ecrã —
   em vez de tudo empilhado num só bloco central. */

.entrada-screen {
  position: absolute;
  inset: 0;
  transition: opacity 1.4s ease;
}
.entrada-screen.exit { opacity: 0; }

.bg-cover.entrada-bg {
  transform: scale(1.14);
}
.bg-cover.entrada-bg.zooming {
  animation: heroKenBurns 9s ease-out forwards;
}
.overlay-dark.entrada-overlay {
  background: linear-gradient(to bottom, rgba(0,0,0,0.62) 0%, rgba(0,0,0,0.4) 32%, rgba(0,0,0,0.48) 68%, rgba(0,0,0,0.95) 100%);
  opacity: 0;
  animation: heroFadeIn 2s ease forwards;
}

/* Logo/título/barra de carregamento só aparecem depois de escolhido o
   idioma (ver JS) — antes disso ficam invisíveis e sem interação. */
.hero-screen#heroEntrada {
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s ease;
}
.hero-screen#heroEntrada.entrada-anim {
  opacity: 1;
  pointer-events: auto;
}
@keyframes heroKenBurns {
  from { transform: scale(1.14); }
  to   { transform: scale(1); }
}
@keyframes heroFadeIn {
  to { opacity: 1; }
}

/* Bloco de marca — ancorado um pouco acima do centro geométrico do ecrã */
.capa-content {
  position: absolute;
  left: 50%; top: 42%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: 90%;
  text-align: center;
}
.capa-logo {
  height: 13.2cqw;
  width: 13.2cqw;
  margin: 0 auto 0.4cqw;
}
.capa-brand {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 3.8cqw;
  background: var(--white-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  letter-spacing: 0.3cqw;
  line-height: 1.15;
  margin: 0 0 1.5cqw;
}
/* Carregamento — fixado ao fundo do ecrã, com percentagem numérica */
.capa-loading-wrap {
  position: absolute;
  left: 0; right: 0; bottom: 6.8%;
  margin: 0 auto;
  z-index: 2;
  width: 22cqw;
}
.capa-loading-meta {
  display: flex;
  justify-content: center;
  gap: 0.5cqw;
  margin-top: 0.9cqw;
  font-size: 1.05cqw;
  letter-spacing: 0.3px;
  color: rgba(255,255,255,0.7);
}
.capa-loading-pct {
  color: var(--gold-bright);
  font-variant-numeric: tabular-nums;
}

.entrada-anim .capa-loading-wrap {
  opacity: 0;
  animation: heroRise 1s cubic-bezier(.16,.8,.24,1) forwards;
  animation-delay: 1.8s;
}
.entrada-anim .capa-logo {
  opacity: 0;
  /* heroRise (sem drop-shadow) em vez de heroRiseShadow: animar
     filter:drop-shadow() sobre um PNG com transparência tem um bug
     conhecido no Safari/iOS — o compositor por vezes falha a respeitar o
     canal alfa e pinta a camada toda a branco a meio da animação. */
  animation: heroRise 1s cubic-bezier(.16,.8,.24,1) forwards;
  animation-delay: 0.2s;
}
.entrada-anim .capa-brand {
  opacity: 0;
  animation: capaBrandIn 1.1s cubic-bezier(.16,.8,.24,1) forwards;
  animation-delay: 0.7s;
}
@keyframes heroRise {
  from { opacity: 0; transform: translateY(18px); filter: blur(4px); }
  to   { opacity: 1; transform: translateY(0); filter: blur(0); }
}
@keyframes capaBrandIn {
  from { opacity: 0; letter-spacing: 1cqw; filter: blur(6px) drop-shadow(0 3px 8px rgba(0,0,0,0.3)); }
  to   { opacity: 1; letter-spacing: 0.3cqw; filter: blur(0) drop-shadow(0 3px 8px rgba(0,0,0,0.3)); }
}

.hero-autobar {
  width: 100%;
  height: 0.26cqw;
  margin: 0;
  background: rgba(212,175,106,0.25);
  overflow: hidden;
  border-radius: 999px;
}
.hero-autobar-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--gold-dark), var(--gold-bright));
}
/* Só começa a encher quando o idioma é escolhido (classe ligada em JS) — sem
   isto, a animação corria em segundo plano desde que o ecrã de entrada era
   criado (mesmo escondido atrás da escolha de idioma), e podia aparecer já
   cheia quando o formando demorasse a escolher, dessincronizada da própria
   percentagem numérica (essa sim já só começava a contar no clique). */
.hero-autobar-fill.filling {
  animation: heroAutobarFill 6.5s linear forwards;
  animation-delay: 1.8s;
}
@keyframes heroAutobarFill {
  to { width: 100%; }
}

/* ---------------- BOTÕES ---------------- */

.btn-gold {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  gap: 0.45cqw;
  background: linear-gradient(135deg, #f3d998, var(--gold-bright) 45%, var(--gold-dark));
  color: #1a1300;
  font-weight: 700;
  letter-spacing: 0.02em;
  font-size: 0.98cqw;
  border: 1px solid rgba(255,255,255,0.3);
  border-radius: 0.7cqw;
  padding: 0.58cqw 1.9cqw;
  cursor: pointer;
  box-shadow: inset 0 0.08cqw 0 rgba(255,255,255,0.25), 0 0.3cqw 0.8cqw rgba(0,0,0,0.4);
  transition: transform .18s ease, box-shadow .18s ease, filter .18s ease;
}
.btn-gold::after {
  content: "";
  position: absolute;
  top: 0; left: -60%;
  width: 35%; height: 100%;
  background: linear-gradient(115deg, transparent, rgba(255,255,255,0.55), transparent);
  transform: skewX(-20deg);
  transition: left .5s ease;
}
.btn-gold:active { transform: translateY(0); filter: brightness(0.96); }
.btn-gold.btn-retry { background: linear-gradient(135deg, #f0c4b4, #d97a5f, #a8503c); }
.btn-gold .arrow { font-size: 1.15em; display: inline-block; transition: transform .18s ease; }
@media (hover: hover) and (pointer: fine) {
  .btn-gold:hover::after { left: 130%; }
  .btn-gold:hover {
    transform: translateY(-0.15cqw);
    filter: brightness(1.06);
    box-shadow: inset 0 0.12cqw 0 rgba(255,255,255,0.35), 0 0.6cqw 1.5cqw rgba(0,0,0,0.5);
  }
  .btn-gold:hover .arrow { transform: translateX(0.2cqw); }
}

/* ---------------- MENU DE MÓDULOS (assets/layout_menu) ----------------
   Ordem de baixo para cima: fundo aéreo → cartões → gradiente inferior
   (escurece a base dos cartões) → texto (número + título, sempre legível
   por cima do gradiente) → personagens (ficam à frente de tudo, incluindo do
   texto, para poderem "tapar" naturalmente o texto onde se sobrepõem — é
   essa profundidade que já existia antes de o gradiente e o texto serem
   reorganizados). Gradiente e texto têm pointer-events:none, para nunca
   bloquear cliques nos cartões por baixo.
   O texto do canto superior esquerdo segue a "fase" do scroll (setas),
   não o cartão sob o rato — há sempre exactamente 4 fases (uma por
   módulo), navegáveis mesmo que esse módulo ainda esteja bloqueado.
   Os cartões (assets/layout_menu/cards, 546x330) têm um halo/sombra suave
   de ~25px à volta da moldura dourada real — por isso o texto por baixo
   de cada cartão e o cabeçalho "Módulos" estão alinhados a left:65px
   (40px do viewport + 25px do halo), não a left:40px. */

.menu-screen { position: absolute; inset: 0; }
.menu-personagens { z-index: 6; pointer-events: none; }
/* Gradiente gerado em CSS (em vez do PNG layout_menu_gradiente_inferior),
   para controlar com precisão até onde escurece — só a faixa dos cartões,
   nunca por cima das personagens, que têm de ficar sempre por cima dele. */
.menu-gradiente {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background: linear-gradient(to bottom, transparent 0%, transparent 58%, rgba(0,0,0,0.45) 80%, rgba(0,0,0,0.82) 100%);
}

/* Entrada do menu a partir do preto, só logo a seguir à capa (ver
   renderMenu({fadeFromBlack:true}) chamado no fim de renderEntrada). */
.menu-screen.menu-fade-in { animation: fadeIn 1.4s ease; }

/* Saída do menu ao dar play, em duas fases bem lentas e suaves:
   fase 1 — tudo o que não é o fundo aéreo (texto, cartões, personagens,
   gradiente) desvanece primeiro, devagar, ficando só o fundo aéreo visível;
   fase 2 — só depois é que o vídeo de descida entra por cima desse fundo e
   desvanece de opacidade 0 a 1 (ver .video-crossfade abaixo e o click em
   .menu-card.disponivel / MENU_EXIT_STAGE1_DUR em main.js).
   Dentro da fase 1, os cartões saem primeiro e as personagens só começam a
   desvanecer meio segundo depois (transition-delay) — como as personagens
   ficam por cima da fila de cartões (z-index maior), desvanecerem ambos ao
   mesmo ritmo deixava ver os cartões a transparecer por trás delas a meio
   da transição; desfasando-as, os cartões já não estão lá quando as
   personagens começam a ficar translúcidas. */
.menu-info,
.menu-modules-head,
.menu-track-viewport,
.menu-labels-viewport,
.menu-gradiente {
  transition: opacity 1s ease-in-out;
}
.menu-personagens {
  transition: opacity 1s ease-in-out .6s;
}
.menu-screen.menu-exit .menu-info,
.menu-screen.menu-exit .menu-modules-head,
.menu-screen.menu-exit .menu-track-viewport,
.menu-screen.menu-exit .menu-labels-viewport,
.menu-screen.menu-exit .menu-personagens,
.menu-screen.menu-exit .menu-gradiente {
  opacity: 0;
}

.video-crossfade {
  opacity: 0;
  transition: opacity 1.4s ease-in-out;
}
.video-crossfade.in {
  opacity: 1;
}

.menu-info {
  position: absolute;
  z-index: 3;
  left: 65px;
  top: 215px;
  width: 760px;
}
.menu-info-anim { animation: menuInfoFade .4s ease; }
@keyframes menuInfoFade {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.menu-info-title {
  font-family: var(--font-serif);
  font-size: 74px;
  line-height: 1.16;
  white-space: pre-line;
  background: var(--gold-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  margin: 0 0 6px;
}
.menu-info-desc {
  font-size: 20px;
  line-height: 1.65;
  white-space: pre-line;
  color: var(--white);
  opacity: 0.88;
  margin: 0;
}

.menu-modules-head {
  position: absolute;
  z-index: 3;
  left: 65px;
  top: 615px;
  display: flex;
  align-items: center;
  gap: 20px;
}
.menu-modules-label {
  font-family: var(--font-sans);
  font-size: 30px;
  font-weight: 600;
  background: var(--gold-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.menu-arrows { display: flex; gap: 10px; }
.menu-arrows .icon-btn:disabled,
.menu-arrows .icon-btn:disabled:hover {
  opacity: 0.3;
  cursor: not-allowed;
  background: linear-gradient(160deg, rgba(255,255,255,0.10), rgba(0,0,0,0.35) 60%);
  color: var(--gold-bright);
  transform: none;
  box-shadow: inset 0 2px 0 rgba(255,255,255,0.18), inset 0 -2px 4px rgba(0,0,0,0.5), 0 2px 5px rgba(0,0,0,0.5);
}

.menu-track-viewport {
  position: absolute;
  z-index: 3;
  left: 0;
  top: 665px;
  width: 1920px;
  height: 400px;
  overflow: hidden;
}
.menu-track {
  position: absolute;
  inset: 0;
  display: flex;
  gap: 2px;
  transition: transform .45s cubic-bezier(.22,.61,.36,1);
}
.menu-card {
  position: relative;
  flex: 0 0 546px;
  display: flex;
  flex-direction: column;
}
.menu-card-art {
  position: relative;
  width: 546px;
  height: 330px;
  background-size: cover;
  background-position: center;
}
.menu-card-icon { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.menu-card-icon svg { width: 64px; height: 64px; }
/* Hover muito suave — só sobre a foto (inset de 25px, a mesma margem do halo
   da moldura dourada em assets/layout_menu/cards), nunca sobre a borda nem
   fora do cartão. */
.menu-card-hover-fx {
  position: absolute;
  inset: 25px;
  border-radius: 18px;
  background: rgba(255,255,255,0.16);
  opacity: 0;
  transition: opacity .25s ease;
  pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
  .menu-card:hover .menu-card-hover-fx { opacity: 1; }
}

.menu-card.disponivel { cursor: pointer; }
.menu-card.bloqueado { cursor: not-allowed; }

/* Camada dos textos (número + título), à parte da dos cartões — fica por
   cima do gradiente (z-index 4) para se manter sempre legível, mas por
   baixo das personagens (z-index 6), que continuam a poder "tapar" o texto
   onde se sobrepõem, tal como antes — ver nota em renderMenu (main.js) sobre
   porque não pode viver dentro do próprio cartão. Mesma largura/gap/scroll
   da .menu-track-viewport, só que arrancando onde a arte do cartão acaba
   (330px) menos os 14px que already se sobrepunham, para ficar exatamente
   onde estava visualmente. pointer-events:none deixa o clique passar para o
   cartão por baixo. */
.menu-labels-viewport {
  position: absolute;
  z-index: 5;
  left: 0;
  top: 981px;
  width: 1920px;
  height: 84px;
  overflow: hidden;
  pointer-events: none;
}
.menu-labels-track {
  position: absolute;
  inset: 0;
  display: flex;
  gap: 2px;
  transition: transform .45s cubic-bezier(.22,.61,.36,1);
}
.menu-label-item {
  flex: 0 0 546px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0 25px;
}
.menu-card-num {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--gold-bright);
}
.menu-card-title { font-size: 20px; font-weight: 600; color: var(--white); }

.menu-label-item.bloqueado,
.menu-label-item.concluido { opacity: 0.55; }
.menu-label-item.concluido .menu-card-num { color: var(--white); }


/* ---------------- VÍDEO ---------------- */

.video-screen { position: absolute; inset: 0; background: #000; display: flex; align-items: center; justify-content: center; }
.video-screen:not(.video-crossfade) { animation: fadeIn .6s ease; }
.video-screen video { width: 100%; height: 100%; object-fit: cover; }

/* ---------------- CENA (fachada / receção) ---------------- */


.hotspot {
  position: absolute;
  width: 58px; height: 58px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(10,10,10,0.7);
  border: 2px solid var(--gold-bright);
  display: flex; align-items: center; justify-content: center;
  z-index: 20;
  animation: pulse 1.8s ease-in-out infinite;
}
.hotspot::before, .hotspot::after {
  content: "";
  position: absolute;
  background: var(--gold-bright);
}
.hotspot::before { width: 22px; height: 3px; }
.hotspot::after { width: 3px; height: 22px; }
@media (hover: hover) and (pointer: fine) {
  .hotspot:hover {
    background: var(--gold-gradient);
    border-color: #fff;
  }
  .hotspot:hover::before, .hotspot:hover::after { background: #1a1300; }
}

@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(233,201,119,0.55); }
  50% { box-shadow: 0 0 0 12px rgba(233,201,119,0); }
}

.curso-overlay {
  position: absolute; inset: 0;
  background: rgba(0,0,0,0.8);
  display: flex; align-items: center; justify-content: center;
  z-index: 15;
}
.curso-box {
  background: var(--card-bg);
  border: 2px solid var(--gold-bright);
  border-radius: 12px;
  padding: 36px 54px;
  max-width: 700px;
  text-align: center;
}
.curso-box p { font-size: 21px; color: var(--white); margin: 0 0 10px; }
.curso-hint { font-size: 14px; color: var(--gold-bright); letter-spacing: .5px; }

/* Cartão de fala — usa sempre a base fornecida (assets/layout_fala_...), que já
   traz o avatar e a caixa vazia desenhados num canvas de 1920x1080. O texto e o
   botão são sobrepostos exatamente sobre essa caixa, nunca construída de novo. */
.card-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 10;
  pointer-events: none;
  object-fit: fill;
}

/* Resumo da situação — barra fixa (assets/layout_resumo_situação_escolha_multipla)
   que fica logo por cima do balão de escolha múltipla, para o formando não
   perder de vista a pergunta do cliente enquanto escolhe a resposta. Caixa
   medida diretamente no ficheiro PNG (script Python/PIL), tal como as outras
   caixas dos templates de fala. */
.resumo-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 9;
  pointer-events: none;
  object-fit: fill;
}
.resumo-text {
  position: absolute;
  left: 24.3%;
  top: 70.2%;
  width: 71.9%;
  height: 5.7%;
  z-index: 9;
  display: flex;
  align-items: center;
  padding: 0 1.6cqw;
  font-size: 1.05cqw;
  font-weight: 700;
  line-height: 1.3;
  color: var(--white);
}
.resumo-label {
  font-family: var(--font-sans);
  font-weight: 700;
  font-style: italic;
  margin-right: 0.4cqw;
  flex-shrink: 0;
  color: #deb76f;
}
/* Algumas traduções da frase de contexto ficam um pouco mais compridas do
   que o original e não cabem numa só linha na caixa fixa — usada só na(s)
   situação(ões) marcada(s) com resumoCompact em data.js (ver
   renderOptionsScreen em main.js), em vez de reduzir o tamanho de letra em
   todas as outras que já cabem bem. */
.resumo-text-compact { font-size: 0.97cqw; }

/* Retângulo da caixa vazia dentro do template 1920x1080, em percentagem
   (medido diretamente nos ficheiros PNG — ver secção 3.1 do guião) */
.card-content {
  position: absolute;
  left: 16.1%;
  top: 77.7%;
  width: 79.9%;
  height: 17.8%;
  z-index: 11;
  box-sizing: border-box;
  padding: 1.4cqw 3.2cqw 1.4cqw 9.8cqw;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 2.4cqw;
}
/* O nome fica sempre à mesma altura (topo da caixa), quer a fala seja curta
   quer longa; só o botão é que se ancora ao canto inferior direito. */
.card-content .btn-gold { align-self: flex-end; }
/* Escolha múltipla: 3 linhas em vez de 1, por isso liberta o máximo de
   respiração vertical possível dentro da caixa (sem tocar no tamanho da
   letra) reduzindo a almofada de cima/baixo que só faz sentido para uma
   única linha centrada. */
.card-content.tight {
  padding-top: 0.35cqw;
  padding-bottom: 0.35cqw;
  align-items: center;
}
.card-text-wrap {
  flex: 1;
  min-width: 0;
  max-height: 100%;
  overflow-y: auto;
}
.card-name {
  display: flex;
  align-items: center;
  gap: 0.65cqw;
  font-family: var(--font-serif);
  font-weight: 700;
  color: #deb76f;
  font-size: 1.55cqw;
  margin-bottom: 0.3cqw;
}
.card-text {
  font-size: 1.15cqw;
  line-height: 1.4;
  color: var(--white);
}
.card-text.typing::after {
  content: "";
  display: inline-block;
  width: 0.14em;
  height: 1em;
  margin-left: 0.05em;
  background: var(--gold-bright);
  vertical-align: -0.12em;
  animation: caretBlink 0.85s step-end infinite;
}
@keyframes caretBlink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}
.card-content .btn-gold {
  flex-shrink: 0;
  font-size: 1cqw;
  padding: 0.6cqw 1.8cqw;
  /* Encosta o botão ao canto inferior direito do balão. Usa
     position:relative em vez de margin, para não mexer no layout nem
     colidir com o transform já usado pela animação de :hover. */
  position: relative;
  left: 2.35cqw;
  bottom: -0.26cqw;
}
/* "Tentar Novamente" tem texto bem mais comprido que "Continuar" — reduz o
   preenchimento lateral só nesta variante para não ficar demasiado alongado. */
.card-content .btn-gold.btn-retry {
  padding-left: 1.1cqw;
  padding-right: 1.1cqw;
}

@container (max-width: 480px) {
  .card-name, .card-text, .card-content .btn-gold { font-size: 3.6cqw; }
  .card-content { flex-direction: column; align-items: stretch; gap: 1cqw; padding: 2cqw 3cqw; }
  .card-content .btn-gold { align-self: center; }
}

/* Opções de escolha múltipla — vivem DENTRO do balão de fala do utilizador
   ("Tu"), como se cada opção fosse uma fala normal: mesmo tamanho e posição
   de texto que qualquer .card-text. Sem balão próprio por opção — só uma
   forma suave ao passar o rato, para se perceber que é clicável. */
.opt-lines {
  display: flex;
  flex-direction: column;
  gap: 0.35cqw;
  max-height: 100%;
  overflow-y: auto;
}
.opt-line {
  display: flex;
  align-items: baseline;
  gap: 0.5cqw;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: 0.35cqw;
  padding: 0.15cqw 0.5cqw 0.15cqw 0.85cqw;
  margin: 0;
  font-size: 1.15cqw;
  line-height: 1.35;
  color: var(--white);
  font-family: inherit;
  transition: background .15s ease;
}
.opt-line .opt-letter {
  flex-shrink: 0;
  font-family: var(--font-serif);
  font-weight: bold;
  background: var(--gold-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.opt-line .opt-text { flex: 1; white-space: pre-line; }
@media (hover: hover) and (pointer: fine) {
  .opt-line:hover:not(:disabled) { background: rgba(212,175,106,0.16); }
}
.opt-line:disabled { opacity: 0.45; cursor: default; }

/* Selo de veredito, escrito dentro da própria caixa de fala (junto ao nome da
   Joana) — não é uma caixa nova, só texto extra dentro do template existente */
.feedback-tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  font-size: 0.85cqw;
  font-family: var(--font-sans);
  font-weight: 400;
  padding: 0.32cqw 0.7cqw 0.38cqw;
  border-radius: 20px;
}
.feedback-tag.correct { background: rgba(63,174,92,0.18); color: var(--green); border: 1px solid var(--green); }
.feedback-tag.wrong { background: rgba(217,83,79,0.18); color: var(--red); border: 1px solid var(--red); }

/* Vinheta por cima do fundo no ecrã de feedback — reforça visualmente se a
   resposta foi certa ou errada, sem tapar o cartão nem o texto. */
.feedback-tint {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  animation: feedbackTintIn 0.4s ease forwards;
}
.feedback-tint.correct { background: radial-gradient(ellipse at center, transparent 35%, rgba(63,174,92,0.45) 100%); }
.feedback-tint.wrong { background: radial-gradient(ellipse at center, transparent 35%, rgba(217,83,79,0.45) 100%); }
@keyframes feedbackTintIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Vinheta escura e pulsante no ecrã de escolha de resposta — reforça o clima
   de tensão enquanto o sfx_suspense_perguntas toca em loop (ver playLoop em
   main.js), sem tapar o balão nem o texto das opções. */
.suspense-tint {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(ellipse at center, transparent 22%, rgba(0,0,0,0.85) 100%);
  animation: suspenseTintPulse 2.03s ease-in-out infinite;
}
/* Sincronizado com a forma de onda real do sfx_suspense_perguntas.mp3 (ver
   esquema desenhado pelo utilizador por cima do waveform no Audition): as
   duas "ondas grandes" (pancadas fortes) acontecem a 0% e a 100% do ciclo
   (repete a cada ~2.03s) — é aí que a vinheta fica mais forte. Entre elas
   (o silêncio relativo) fica mais fraca, mas nunca desaparece por completo,
   só um respirar suave e contínuo. */
@keyframes suspenseTintPulse {
  0%   { opacity: 1; }
  60%  { opacity: 0.3; }
  100% { opacity: 1; }
}

/* ---------------- ECRÃ FINAL (fim do curso) ----------------
   Mesma linguagem visual do ecrã de resumo de boas práticas (painel escuro,
   borda dourada, título serifado branco), só que num único cartão central
   mais estreito, por não ter colunas de conteúdo. */
.final-screen {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2cqw;
}
.final-panel {
  position: relative;
  z-index: 2;
  width: 46cqw;
  max-width: 860px;
  background: rgba(12, 11, 11, 0.97);
  border: 2px solid var(--gold-bright);
  border-radius: 22px;
  padding: 3.6cqw 4.4cqw 1.6cqw;
  text-align: center;
  box-shadow: 0 2.5cqw 5cqw rgba(0,0,0,0.55), 0 0 3cqw rgba(222,183,111,0.08);
  overflow: hidden;
}
.final-panel::before {
  content: "";
  position: absolute;
  top: 0; left: 10%; right: 10%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(222,183,111,0.9), transparent);
}
.final-badge {
  width: 3.6cqw;
  height: 3.6cqw;
  min-width: 42px;
  min-height: 42px;
  margin: 0 auto 1.1cqw;
  position: relative;
  top: -0.5cqw;
}
.final-badge svg { width: 100%; height: 100%; }
.final-header { margin-bottom: 2.3cqw; }
.final-eyebrow {
  display: block;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.85cqw;
  letter-spacing: 0.2cqw;
  text-transform: uppercase;
  color: var(--gold-bright);
  margin-top: 0.7cqw;
}
.final-title {
  font-family: var(--font-serif);
  font-size: 3.2cqw;
  line-height: 1.15;
  color: var(--white);
  margin: 0;
  letter-spacing: 0.02em;
}
.final-rule {
  display: block;
  width: 4.6cqw;
  height: 1px;
  margin: 1cqw auto 0;
  background: linear-gradient(90deg, transparent, var(--gold-bright), transparent);
}
/* position:relative + top negativo em vez de mexer no padding/margin do
   painel — sobe visualmente o ícone e o botão sem alterar a altura do frame
   (o espaço reservado no fluxo do layout mantém-se igual). */
.final-panel .btn-gold { display: inline-flex; margin: 2.2cqw auto 0; position: relative; top: -1.4cqw; }

/* Créditos fora do frame, encostados ao fundo do ecrã (não do painel) — ver
   renderFinal em main.js, onde ficam como irmãos do .final-panel dentro de
   .final-screen, posicionados de forma absoluta e independente do painel. */
.final-credit-line1 { font-size: 0.89cqw; font-weight: 600; }
.final-credit-strong { font-weight: 600; }
.final-footer-credit {
  position: absolute;
  left: 50%;
  bottom: 1.7cqw;
  width: max-content;
  max-width: 90%;
  transform: translateX(-50%);
  z-index: 2;
  text-align: center;
  font-size: 0.78cqw;
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: #ffffff;
}
.final-footer-credit a {
  color: inherit;
  text-decoration: none;
  transition: color .15s ease;
}
@media (hover: hover) and (pointer: fine) {
  .final-footer-credit a:hover { color: var(--gold-bright); text-decoration: underline; }
}

/* Animações de entrada, leves e escalonadas — mesmo padrão do ecrã de resumo */
@keyframes finalPanelIn {
  from { opacity: 0; transform: translateY(22px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes finalFadeUpIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Igual à finalFadeUpIn, mas para elementos que já usam transform:translateX(-50%)
   para se centrarem (ver .final-footer-credit) — uma animação de transform
   substitui por completo o transform estático da regra base enquanto corre
   (não os combina), por isso tem de incluir aqui o próprio -50% ou perdia-se
   a centragem assim que a animação terminasse. */
@keyframes finalFadeUpInCentered {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
.final-panel { animation: finalPanelIn 0.6s cubic-bezier(.22,.61,.36,1) both; }
.final-badge { animation: finalFadeUpIn 0.5s ease-out both; animation-delay: 0.1s; }
.final-panel .btn-gold { animation: finalFadeUpIn 0.5s ease-out both; animation-delay: 0.3s; }
.final-footer-credit { animation: finalFadeUpInCentered 0.5s ease-out both; animation-delay: 0.45s; }

/* ---------------- RESUMO DE BOAS PRÁTICAS (fim de módulo) ---------------- */

.resumo-screen {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2cqw;
}
.resumo-panel {
  position: relative;
  z-index: 2;
  width: 84cqw;
  max-width: 1560px;
  background: rgba(12, 11, 11, 0.97);
  border: 2px solid var(--gold-bright);
  border-radius: 22px;
  padding: 2.9cqw 4.1cqw 3.3cqw;
  box-shadow: 0 2.5cqw 5cqw rgba(0,0,0,0.55), 0 0 3cqw rgba(222,183,111,0.08);
  overflow: hidden;
}
.resumo-panel::before {
  content: "";
  position: absolute;
  top: 0; left: 10%; right: 10%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(222,183,111,0.9), transparent);
}
.resumo-header { position: relative; text-align: center; margin-bottom: 1.7cqw; }
.resumo-title {
  font-family: var(--font-serif);
  font-size: 2.15cqw;
  line-height: 1.28;
  letter-spacing: 0.02em;
  margin: 0;
  color: var(--white);
}
.resumo-rule {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4.6cqw;
  height: 1px;
  margin: 1cqw auto 0;
  background: linear-gradient(90deg, transparent, var(--gold-bright), transparent);
}
.resumo-rule::before {
  content: "";
  width: 0.35cqw;
  height: 0.35cqw;
  background: var(--gold-bright);
  border-radius: 50%;
  transform: rotate(45deg);
}
.resumo-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5cqw;
  margin-bottom: 1.6cqw;
}
.resumo-col {
  position: relative;
  border-radius: 14px;
  padding: 1.35cqw 1.6cqw;
  border: 1px solid rgba(255,255,255,0.08);
  border-top: 2px solid rgba(255,255,255,0.2);
  overflow: hidden;
}
.resumo-col-fazer { background: linear-gradient(165deg, rgba(63,174,92,0.13), rgba(63,174,92,0.03)); border-top-color: var(--green); }
.resumo-col-evitar { background: linear-gradient(165deg, rgba(217,83,79,0.13), rgba(217,83,79,0.03)); border-top-color: var(--red); }
.resumo-col h3 {
  margin: 0 0 0.95cqw;
  font-size: 1.02cqw;
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--white);
}
.resumo-col-fazer h3 { color: var(--green); }
.resumo-col-evitar h3 { color: var(--red); }
.resumo-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.8cqw; }
.resumo-col li {
  display: flex;
  align-items: flex-start;
  gap: 0.65cqw;
  font-size: 0.98cqw;
  line-height: 1.5;
  color: var(--white);
  opacity: 0.94;
  padding-bottom: 0.8cqw;
  border-bottom: 1px solid rgba(255,255,255,0.07);
}
.resumo-col li:last-child { padding-bottom: 0; border-bottom: none; }
.resumo-icon { flex-shrink: 0; width: 1.2cqw; height: 1.2cqw; margin-top: 0.1cqw; }
.resumo-icon svg { width: 100%; height: 100%; }
.resumo-quote {
  position: relative;
  text-align: center;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.1cqw;
  line-height: 1.5;
  color: var(--gold-bright);
  max-width: 80%;
  margin: 0 auto 1.6cqw;
  padding-top: 1.4cqw;
}
.resumo-quote::before {
  content: "“";
  position: absolute;
  top: -0.55cqw;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-serif);
  font-style: normal;
  font-size: 2.8cqw;
  color: rgba(222,183,111,0.35);
  line-height: 1;
}
.resumo-panel .btn-gold { display: flex; margin: 0 auto; }

/* Animações de entrada, leves e escalonadas — painel primeiro, depois as
   duas colunas (uma de cada lado) e por fim a citação e o botão. */
@keyframes resumoPanelIn {
  from { opacity: 0; transform: translateY(22px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes resumoColLeftIn {
  from { opacity: 0; transform: translateX(-16px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes resumoColRightIn {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes resumoFadeUpIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
.resumo-panel { animation: resumoPanelIn 0.6s cubic-bezier(.22,.61,.36,1) both; }
.resumo-col-fazer { animation: resumoColLeftIn 0.55s ease-out both; animation-delay: 0.18s; }
.resumo-col-evitar { animation: resumoColRightIn 0.55s ease-out both; animation-delay: 0.28s; }
.resumo-quote { animation: resumoFadeUpIn 0.5s ease-out both; animation-delay: 0.42s; }
.resumo-panel .btn-gold { animation: resumoFadeUpIn 0.5s ease-out both; animation-delay: 0.52s; }
