/* ==========================================================================
   TOAST DE AVISO — prefixo tst-
   Pilha fixa num canto da tela, no máximo três avisos por vez, cada um com
   ícone de tom, texto, botão de fechar e uma régua de tempo que encolhe.

   Tokens usados:
     --accent           ícone do tom "ok" e a régua em progresso
     --fg               texto do aviso, ícone do tom "atenção"
     --fg-2             ícone do tom "info", botão de fechar em repouso
     --rule             trilho em repouso da régua de tempo
     --ease             curva única do projeto
     --sans             face do texto do aviso
     --radius-media     canto do cartão (0 em projeto flat, e está certo)
     --radius-pill      régua e botão de fechar, os dois circulares/pílula
   Primitiva do core em uso: .glass (superfície do cartão).

   POR QUE NÃO HÁ TOKEN DE COR POR TOM: só existe --accent como cor de marca
   na biblioteca. "Verde de sucesso" e "vermelho de alerta" não têm token —
   e --tst-ok/--tst-atencao seriam cor crua disfarçada de variável, o que o
   §6.6 do contrato proíbe do mesmo jeito. A diferença de tom sai por ÍCONE
   (três <svg> no markup, um por tom, só um visível por vez) e por PAPEL de
   acessibilidade (role="status" vs "alert", escrito pelo script) — nunca por
   matiz. Ver ficha.md, seção "O que o contrato não deixou".
   ========================================================================== */

/* Fileira dos três gatilhos de exemplo (um por tom). Não é a peça — é o
   convite a clicar nela; um site consumidor troca por botões reais e pode
   apagar esta regra junto com o markup de exemplo. */
.tst-demo{
  margin-top:clamp(26px,4vh,40px);
  display:flex;
  flex-wrap:wrap;
  gap:14px;
}
.tst-pilha{
  --tst-inset:clamp(14px,2.4vw,26px);
  --tst-gap:12px;
  --tst-largura:360px;
  /* Bate com a duração da transição de .tst-item, logo abaixo. O script lê
     este número (SAIDA_MS) para saber quando remover o nó da pilha — mudar
     um pede mudar o outro. */
  --tst-saida:.36s;

  position:fixed;
  right:var(--tst-inset);
  bottom:var(--tst-inset);
  z-index:900;
  display:flex;
  flex-direction:column;
  /* Novo aviso entra no fim da lista (mais perto do canto); o mais antigo
     fica no topo da pilha e é o primeiro a sair — nem por acaso é também
     o primeiro a ser empurrado quando chega o quarto. */
  gap:var(--tst-gap);
  width:var(--tst-largura);
  max-width:calc(100vw - (var(--tst-inset) * 2));
  /* A caixa da pilha não tem fundo próprio: só existe para posicionar. Sem
     pointer-events:none aqui, a folga entre avisos (gap) e a sobra abaixo do
     último bloquearia clique na página por baixo, mesmo estando vazia. */
  pointer-events:none;
}

/* ==========================================================================
   O INVÓLUCRO — entrada, saída e o colapso de altura
   Truque grid-template-rows: 0fr -> 1fr. Funciona sem o script medir um
   pixel sequer, e é o que faz os avisos de baixo SUBIREM ao vivo quando um
   de cima sai, em vez de a pilha simplesmente encolher de repente.
   ========================================================================== */
.tst-item{
  display:grid;
  grid-template-rows:0fr;
  opacity:0;
  filter:blur(14px);
  pointer-events:auto;
  transition:grid-template-rows var(--tst-saida) var(--ease),
             opacity .3s var(--ease),
             filter .38s var(--ease);
}
.tst-item.is-shown{
  grid-template-rows:1fr;
  opacity:1;
  filter:blur(0);
}

/* Movimento reduzido desliga só o que anda SOZINHO — a entrada e a saída do
   invólucro. A régua de tempo (mais abaixo) nem precisa de regra aqui: ela
   nunca teve transition própria, então já não anima em nenhum dos dois
   casos. filter:none em vez de deixar herdado: blur(14px) parado no meio
   travaria o aviso meio-transparente para sempre em quem pediu menos
   movimento. Colada à regra que desliga, como manda o §6.6 do contrato. */
@media(prefers-reduced-motion:reduce){
  .tst-item{transition-duration:.01ms;filter:none}
}

.tst-caixa{
  /* As duas linhas que fazem o grid-rows valer: sem min-height:0 o item de
     grid nunca encolhe abaixo do conteúdo, e sem overflow:hidden o texto
     vaza da caixa de altura zero antes de ela crescer. */
  min-height:0;
  overflow:hidden;
  border-radius:var(--radius-media);
  padding:14px 14px 12px;
}

.tst-linha{
  display:flex;
  align-items:flex-start;
  gap:11px;
}

.tst-icone{
  display:none;
  flex:0 0 20px;
  margin-top:1px;
}
/* Só o ícone do tom corrente aparece — data-tst-tom é escrito pelo script no
   próprio .tst-item, no instante em que o aviso é montado. */
.tst-item[data-tst-tom="ok"] .tst-icone-ok{display:block;color:var(--accent)}
.tst-item[data-tst-tom="info"] .tst-icone-info{display:block;color:var(--fg-2)}
.tst-item[data-tst-tom="atencao"] .tst-icone-atencao{display:block;color:var(--fg)}

.tst-texto{
  flex:1 1 auto;
  font-family:var(--sans);
  font-size:14px;
  line-height:1.5;
  color:var(--fg);
}

.tst-fechar{
  flex:0 0 auto;
  width:26px;height:26px;padding:0;margin:-2px -2px 0 0;
  display:grid;place-items:center;
  border-radius:var(--radius-pill);
  background:none;border:0;color:var(--fg-2);
  transition:color .25s var(--ease);
}
.tst-fechar:hover,
.tst-fechar:focus-visible{color:var(--accent)}

/* ==========================================================================
   RÉGUA DE TEMPO
   O script escreve transform:scaleX(fração) A CADA QUADRO, por dt (nunca
   por quadro cru — teto de 50ms, contrato §3/§7). Por isso a barra NÃO leva
   transition própria: uma transição brigaria com um valor que já muda a
   cada ~16ms, e a régua perderia a leitura fina do tempo restante — inclusive
   com movimento reduzido, onde ela é a ÚNICA coisa que ainda se move, porque
   é informação (quanto falta), não enfeite.
   ========================================================================== */
.tst-regua{
  position:relative;
  height:2px;
  margin-top:11px;
  background:var(--rule);
  border-radius:var(--radius-pill);
  overflow:hidden;
}
.tst-regua-barra{
  position:absolute;inset:0;
  transform:scaleX(1);
  transform-origin:left;
  background:var(--accent);
}

/* ==========================================================================
   MOBILE — faixa inferior, não canto
   Sob o dedo um cartão de 360px ancorado no canto sobra fora da mira; a
   pilha vira uma faixa que ocupa a largura útil, ainda encostada embaixo.
   ========================================================================== */
@media(max-width:560px){
  .tst-demo .btn{width:100%}
  .tst-pilha{
    left:var(--tst-inset);
    right:var(--tst-inset);
    width:auto;
    max-width:none;
  }
}
