/* ==========================================================================
   ETAPAS EM ABAS COM REPRODUÇÃO — prefixo eta-
   Lista de etapas à esquerda (role="tablist"), painel de mídia à direita,
   e três discos de reprodução acima. A etapa ativa abre a descrição e o
   filete embaixo dela enche no tempo da etapa.

   Tokens usados:
     --bg --fg --fg-2 --fg-muted   tinta e superfície, do escopo da seção
     --rule                        trilho do filete e fio da ressalva
     --dark --light                o véu e a tinta da legenda, que está sobre
                                   FOTO e não sobre o fundo do escopo
     --accent                      o filete que enche (é GRÁFICO, não texto)
     --accent-ink                  o número da etapa ativa (é TEXTO sobre o
                                   fundo do escopo — MANUAL §3; o var() traz
                                   --accent de fallback para quem colar a
                                   dobra fora de um escopo de tom)
     --display --sans              tipografia
     --ease                        curva do projeto
     --radius-media                canto do painel
     --nota-max                    medida da ressalva (parafuso da primitiva)
   A coluna vem do .wrap do core: --max e --pad não são lidos aqui.

   UM RELÓGIO SÓ. --eta-dur é o tempo de cada etapa, e ele é lido em dois
   lugares que não podem discordar: a animação do filete (aqui) e o
   setTimeout do script, que a pega por getComputedStyle na raiz. Nunca há
   dois números para manter em sincronia.

   O FILETE É CSS, NÃO JAVASCRIPT ESCREVENDO LARGURA POR QUADRO. A regra
   que anima casa com a aba de aria-selected="true", e só com ela — então
   trocar de etapa tira a regra de uma aba e a põe na outra, e uma animação
   que passa a casar COMEÇA DO ZERO. O reinício a cada troca é de graça, e
   não custa uma linha de script. Pausar é animation-play-state, escrito
   numa regra mais específica que a shorthand (ver abaixo).
   ========================================================================== */

.eta{
  /* Relógio da dobra: quanto cada etapa fica em cena. Seis segundos é o
     tempo de ler uma descrição de ~45 palavras sem correr. Abaixo de 4s a
     troca vira pisca-pisca; acima de 9s a dobra parece travada e o filete
     parece parado. O script lê ESTE valor. */
  --eta-dur:6s;

  /* Fusão entre um painel e o seguinte. */
  --eta-swap:.7s;

  /* Abertura e fecho da descrição. Mais curta que a fusão do painel de
     propósito: o texto precisa ter assentado antes de a foto terminar de
     trocar, senão as duas coisas se movem ao mesmo tempo e o olho não sabe
     para onde ir. */
  --eta-open:.44s;

  /* Desfoque da fusão do painel. Nada entra seco (contrato §5). */
  --eta-blur:14px;

  /* Corpo do título de cada etapa. */
  --eta-rot:clamp(17px,1.5vw,21px);

  /* Proporção do palco. 16/11 é a caixa que mais se aproxima da altura da
     coluna de quatro etapas sem cortar demais uma foto 16/9. */
  --eta-palco:16 / 11;
}

/* ===== CABEÇALHO ===== */

.eta-head{
  display:grid;
  grid-template-columns:minmax(0,1fr) auto;
  align-items:end;
  column-gap:clamp(24px,4vw,64px);
}
.eta-head-txt{min-width:0}

/* OS TRÊS DISCOS SÓ EXISTEM COM SCRIPT. Sem JavaScript eles não comandam
   nada, e botão que não faz nada é pior que botão que não existe — mesma
   decisão da barra de abas do hero/slideshow-cinematico. Quem escreve
   .is-live é o script, na primeira linha da inicialização.
   O [hidden] do botão de pausa não precisa de regra aqui: quem dá display
   a ele é o .btn-disc do core, e o .btn-play[hidden]{display:none} da
   mesma folha vem depois e vence (§6.5, já resolvido na primitiva). */
.eta-ctl{display:none}
.eta.is-live .eta-ctl{
  display:flex;align-items:center;
  gap:10px;
  padding-bottom:6px;
}
.eta-seta{width:17px;height:17px}

/* ===== GRADE ===== */

.eta-grid{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.04fr);
  column-gap:clamp(28px,4.4vw,72px);
  align-items:start;
  margin-top:clamp(34px,4.6vh,56px);
}
.eta-col{min-width:0}

.eta-lista{
  display:flex;flex-direction:column;
  min-width:0;
}

/* ===== A ABA =====
   Botão de verdade, sem cara de botão. O reset é local porque o .btn do
   core é outra coisa (pílula de rótulo, com fundo e padding fixos), e o
   .btn-disc é o disco de ícone — nenhum dos dois cabe numa linha de lista.

   TUDO É <span>, e não é preguiça: <button> só aceita conteúdo de
   frase, então um <p> ou um <div> aqui dentro seria markup inválido. O
   display vem do CSS, que não liga para isso. */
.eta-aba{
  display:grid;
  grid-template-columns:auto minmax(0,1fr);
  column-gap:clamp(12px,1.4vw,18px);
  width:100%;
  padding:clamp(16px,2.2vh,22px) 0 0;
  border:0;background:none;
  text-align:start;
  color:var(--fg-2);
  transition:color .35s var(--ease);
}
.eta-aba:hover{color:var(--fg)}
.eta-aba[aria-selected="true"]{color:var(--fg)}

.eta-num{
  grid-column:1;grid-row:1;
  font-family:var(--display);font-weight:700;
  font-size:12px;letter-spacing:.1em;line-height:1.7;
  color:var(--fg-muted);
  transition:color .35s var(--ease);
}
/* O número da etapa ativa é TEXTO sobre o fundo do escopo, e por isso lê
   --accent-ink e não --accent: em seção clara o accent puro dá 1.36:1 com
   o sage da Liberta, contra um mínimo de 3:1 (MANUAL §3). O filete logo
   abaixo continua em --accent puro — ele é traço, não glifo. */
.eta-aba[aria-selected="true"] .eta-num{color:var(--accent-ink,var(--accent))}

.eta-rot{
  grid-column:2;grid-row:1;
  font-family:var(--display);font-weight:700;
  font-size:var(--eta-rot);letter-spacing:-.015em;line-height:1.24;
  color:currentColor;
}

/* ===== A DESCRIÇÃO =====
   Fechar e abrir por grid-template-rows de 0fr a 1fr: é a única técnica
   que anima ATÉ A ALTURA DO CONTEÚDO sem um número mágico. max-height
   obrigaria a chutar um teto — e um teto curto corta a descrição longa em
   silêncio, enquanto um teto folgado faz o fecho parecer atrasado, porque
   a transição gasta metade do tempo percorrendo altura que não existe.

   Onde a interpolação entre fr não existe (antes de Chrome 107, Firefox
   120 e Safari 17.2) a troca acontece SEM transição — abre e fecha na
   hora. Nada quebra, e é o degrau certo para uma peça de conteúdo.

   ABERTA É O ESTADO PADRÃO, e isso é o que faz a dobra funcionar sem
   JavaScript: as quatro descrições ficam visíveis, e quem as fecha é o
   .is-live que só o script escreve.

   POR QUE minmax(0,…) E NÃO 0fr/1fr SECOS, e isto foi medido duas vezes:
   `grid-template-rows:0fr` é, por especificação, `minmax(auto,0fr)`, e o
   mínimo automático de um item de grade é o min-content dele — a linha se
   recusa a descer abaixo da altura do texto e a descrição "fechada" fica
   do mesmo tamanho da aberta. Medido: as quatro em 103.938px, fechadas e
   abertas. Zerar o mínimo do ITEM (min-height:0) baixou para 10px, que é
   o padding do filho — o padding continua contando no min-content. Só
   escrever o mínimo na PISTA, com minmax(0,…), fecha de verdade. Medido
   depois: aberta 103.938px, fechada 0px. As duas pontas têm o mesmo
   mínimo, o que também é o que permite a transição interpolar.

   O overflow:hidden mora no invólucro da grade, não no texto: é ele que
   corta o padding do filho enquanto a linha encolhe. */
.eta-desc{
  grid-column:2;grid-row:2;
  display:grid;grid-template-rows:minmax(0,1fr);
  overflow:hidden;
}
.eta-desc-in{
  display:block;
  /* Cinto além do suspensório: o minmax(0,…) da pista já basta, e este
     min-height é o que segura o caso de alguém trocar a pista por `0fr`
     seco sem saber por que ela estava escrita assim. */
  min-height:0;
  padding-top:10px;
  font-size:14.5px;line-height:1.62;letter-spacing:normal;
  color:var(--fg-2);
  max-width:56ch;
}
.eta.is-live .eta-desc{
  grid-template-rows:minmax(0,0fr);
  visibility:hidden;
  transition:grid-template-rows var(--eta-open) var(--ease),
             visibility 0s linear var(--eta-open);
}
/* A visibilidade não é enfeite: ela TIRA a descrição fechada da árvore de
   acessibilidade. Como a descrição mora dentro do <button role="tab">
   (um tablist só pode conter tabs, ver o markup), sem isto o nome da aba
   inativa carregaria as quarenta e cinco palavras dela. O atraso faz o
   texto desaparecer só depois do fecho — sem ele a descrição sumiria de
   uma vez e a altura animaria sozinha, vazia. */
.eta.is-live .eta-aba[aria-selected="true"] .eta-desc{
  grid-template-rows:minmax(0,1fr);
  visibility:visible;
  transition:grid-template-rows var(--eta-open) var(--ease),visibility 0s;
}
/* Quem pediu menos movimento troca de etapa sem ver a altura animar. */
@media(prefers-reduced-motion:reduce){
  .eta.is-live .eta-desc,
  .eta.is-live .eta-aba[aria-selected="true"] .eta-desc{transition:none}
}

/* ===== O FILETE =====
   O trilho de cada aba é também o fio que separa uma etapa da seguinte —
   por isso não há border-bottom na aba: seria uma linha em cima da outra. */
.eta-trilho{
  grid-column:1 / -1;grid-row:3;
  margin-top:clamp(14px,1.8vh,18px);
  height:2px;
  background:var(--rule);
  overflow:hidden;
}
.eta-fill{
  display:block;height:100%;
  background:var(--accent);
  transform:scaleX(0);transform-origin:left center;
}
/* Enche no tempo da etapa. Mesma fonte que o script: --eta-dur.
   A regra casa SÓ com a aba selecionada — é a troca de aba que reinicia a
   animação, porque uma animação que passa a casar começa do zero. */
.eta.is-live .eta-aba[aria-selected="true"] .eta-fill{
  animation:etaFill var(--eta-dur) linear forwards;
}
@keyframes etaFill{
  from{transform:scaleX(0)}
  to{transform:scaleX(1)}
}
/* A PAUSA PRECISA VENCER A SHORTHAND. `animation:etaFill …` é shorthand e
   zera todas as longhands dela, inclusive animation-play-state. A regra
   acima vale (0,5,0); esta soma .is-paused e vale (0,6,0). Escrita com
   menos, o botão de pausa "não funcionaria" — sem erro nenhum no console.
   É a mesma armadilha registrada na ficha do hero/slideshow-cinematico. */
.eta.is-live.is-paused .eta-aba[aria-selected="true"] .eta-fill{
  animation-play-state:paused;
}
/* Sem relógio não há o que contar: o filete SOME. Deixá-lo cheio, como faz
   o slideshow, mentiria menos ali (onde ele é a régua da barra de abas) do
   que aqui, onde ele é a única peça que se move — um filete cheio parado
   embaixo da etapa ativa leria como "esta etapa terminou". */
@media(prefers-reduced-motion:reduce){
  .eta.is-live .eta-aba[aria-selected="true"] .eta-fill{
    animation:none;transform:scaleX(0);
  }
}

/* ===== O PALCO =====
   Os quatro painéis ocupam a mesma caixa, empilhados e absolutos. Quem dá
   altura à caixa é o aspect-ratio, e não o conteúdo — assim a troca nunca
   muda a altura da dobra, qualquer que seja o recorte da foto que entra. */
.eta-palco{
  position:relative;
  min-width:0;
  aspect-ratio:var(--eta-palco);
  border-radius:var(--radius-media);
  overflow:hidden;
  background:color-mix(in srgb,var(--fg) 6%,transparent);
}
.eta-painel{
  position:absolute;inset:0;
  margin:0;
  opacity:0;visibility:hidden;
  transform:scale(1.03);
  filter:blur(var(--eta-blur));
  transition:opacity var(--eta-swap) var(--ease),
             transform var(--eta-swap) var(--ease),
             filter var(--eta-swap) var(--ease),
             visibility 0s linear var(--eta-swap);
}
/* SEM SCRIPT o primeiro painel já nasce com .is-on no markup: a dobra abre
   com foto, e os outros três ficam fora da tela e fora do foco. */
.eta-painel.is-on{
  opacity:1;visibility:visible;
  transform:scale(1);
  filter:blur(0);
  transition:opacity var(--eta-swap) var(--ease),
             transform var(--eta-swap) var(--ease),
             filter var(--eta-swap) var(--ease),
             visibility 0s;
}
.eta-img{
  width:100%;height:100%;
  object-fit:cover;
  /* block-size:auto seria o contrário do que se quer aqui: a imagem TEM de
     preencher a caixa do palco. Por isso os <img> do markup não trazem
     width/height — atributo de dimensão vence o aspect-ratio e o palco
     desandaria (MANUAL §6, armadilha 2). */
}

/* ===== A LEGENDA =====
   Dentro da imagem, ancorada embaixo (contrato §6): embaixo da foto ela
   viraria uma segunda peça.

   O VÉU É ::before DA PRÓPRIA LEGENDA, e não uma faixa de altura fixa no
   palco: véu medido em porcentagem do card é ultrapassado por um texto de
   três linhas em tela estreita, e aí a legenda sai do gradiente (MANUAL
   §6, armadilha 3). Aqui ele cresce com o texto, sempre.
   backdrop-filter sempre acompanhado de máscara em gradiente — caixa reta
   produz borda dura e lê "chapado".

   O z-index:2 aqui não é para subir na pilha: é o que faz a legenda virar
   CONTEXTO DE EMPILHAMENTO, para que o z-index:-1 do véu fique atrás do
   texto e ainda assim acima da foto. Sem ele o véu desce para a pilha do
   painel e some debaixo do <img>. Precedente: midia/grade-cases-foto. */
.eta-legenda{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  padding:clamp(34px,5vw,54px) clamp(16px,2.4vw,26px) clamp(14px,2vw,20px);
  font-family:var(--sans);font-size:13px;line-height:1.5;
  letter-spacing:normal;
  color:var(--light);
  text-wrap:balance;
}
.eta-legenda::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(to top,
             color-mix(in srgb,var(--dark) 82%,transparent) 0%,
             color-mix(in srgb,var(--dark) 52%,transparent) 48%,
             transparent 100%);
  backdrop-filter:blur(7px);
  -webkit-backdrop-filter:blur(7px);
  mask-image:linear-gradient(to top,#000 0%,rgba(0,0,0,.9) 44%,transparent 100%);
  -webkit-mask-image:linear-gradient(to top,#000 0%,rgba(0,0,0,.9) 44%,transparent 100%);
}

/* ===== A RESSALVA =====
   .nota do core carrega a tipografia; daqui saem só margem e alinhamento,
   que são posição e continuam locais (ver o comentário da primitiva). */
.eta-nota{
  margin-top:clamp(28px,4vh,44px);
  padding-top:16px;
  border-top:1px solid var(--rule);
  --nota-max:78ch;
}

/* ===== TOQUE =====
   Onde não há ponteiro, o hover não existe e a aba precisa nascer legível.
   A tinta de repouso já é --fg-2, que fecha contraste sozinha; o que some
   é só o realce de passagem. */
@media(hover:none){
  .eta-aba:hover{color:var(--fg-2)}
  .eta-aba[aria-selected="true"]:hover{color:var(--fg)}
}

/* ===== LARGURA ===== */

/* Abaixo de 940px a grade desaba em uma coluna e o PALCO SOBE, por order.
   É posicionamento, não ordem de leitura: a foto é ilustração da etapa, e
   quem chega por leitor de tela continua ouvindo a lista antes dela. Com o
   palco embaixo, a troca automática aconteceria fora da tela de quem está
   lendo as etapas — o que é o mesmo que não trocar. Precedente:
   conteudo/rolagem-sincronizada. */
@media(max-width:940px){
  .eta-grid{
    grid-template-columns:minmax(0,1fr);
    row-gap:clamp(24px,4vh,38px);
  }
  .eta-palco{order:-1}
  .eta{--eta-palco:16 / 10}
}

@media(max-width:720px){
  .eta-head{
    grid-template-columns:minmax(0,1fr);
    row-gap:22px;
    align-items:start;
  }
  .eta.is-live .eta-ctl{padding-bottom:0}
  .eta{--eta-blur:8px}
  .eta-desc-in{font-size:14px}
  .eta-legenda{font-size:12.5px}
}
