/* =====================================================================
   Acabamento: movimento e resposta ao toque/mouse.
   Todas as animações do app moram aqui, para ficar fácil achar e ajustar.

   Regras que este arquivo segue (e por quê):
   - Só anima "transform" e "opacity". O navegador faz essas duas na placa
     de vídeo, sem recalcular o layout da página: fica liso até em celular fraco.
   - Toda animação tem um motivo: confirmar um toque, mostrar de onde algo
     veio ou evitar que a tela "pisque" de uma vez. Enfeite sem motivo, não.
   - Quanto mais vezes por dia algo acontece, mais curta e discreta é a animação.
   - Curvas e durações vêm das variáveis de base.css (--curva-*, --duracao-*).
   - Hover só com mouse: (hover: hover) and (pointer: fine).
   - Movimento (deslocar, crescer, "afundar") só para quem NÃO pediu menos
     movimento nas configurações do sistema: @media (prefers-reduced-motion: no-preference).
     Para quem pediu, as coisas continuam aparecendo com um fade, sem se mexer.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. Animações reutilizáveis
   Um @keyframes só com "from" anima do valor indicado até o valor normal
   do elemento. Assim a mesma animação serve para qualquer elemento.
   --------------------------------------------------------------------- */

/* Aparece subindo um pouco. Com menos movimento, --deslocamento vale 0: vira só fade */
@keyframes surgir {
  from { opacity: 0; transform: translateY(var(--deslocamento)); }
}

/* Só aparece (sem deslocar) */
@keyframes aparecer {
  from { opacity: 0; }
}

/* Entram de lado: usadas ao trocar de semana e de passo da revisão */
@keyframes vir-da-direita {
  from { opacity: 0; transform: translateX(calc(var(--deslocamento) * 2)); }
}
@keyframes vir-da-esquerda {
  from { opacity: 0; transform: translateX(calc(var(--deslocamento) * -2)); }
}

/* ---------------------------------------------------------------------
   2. Resposta ao toque e ao mouse
   É a coisa mais frequente do app (dezenas de vezes por dia), então é a
   mais rápida: o botão "afunda" um pouquinho enquanto está pressionado.
   Isso confirma que o toque foi sentido antes mesmo de a ação terminar.
   --------------------------------------------------------------------- */
.botao, .fab, .circulo, .filtro, .aba, .semana__dia, .semana__seta,
.botao-icone, .menu__item, .escolha__estrela, .dia-semana, .aviso__acao {
  /* Nunca "transition: all": listar as propriedades evita animar o que não devia */
  transition:
    background-color 150ms ease,
    border-color 150ms ease,
    color 150ms ease,
    opacity 150ms ease,
    transform var(--duracao-toque) var(--curva-saida);
}

/* Cartões que abrem algo ao toque: só a cor muda (e o "afundar", abaixo) */
.cartao {
  transition:
    background-color 150ms ease,
    border-color 150ms ease,
    transform var(--duracao-toque) var(--curva-saida);
}

.secao__link { transition: opacity 150ms ease; }
.secao__link:active { opacity: 0.7; }

@media (prefers-reduced-motion: no-preference) {
  /* Botões comuns: afundam 3% */
  .botao:active:not(:disabled), .filtro:active, .aba:active, .semana__seta:active,
  .dia-semana:active, .aviso__acao:active { transform: scale(0.97); }

  /* Botões pequenos e redondos precisam afundar mais para a gente perceber */
  .fab:active, .circulo:active, .botao-icone:active,
  .escolha__estrela:active:not(:disabled) { transform: scale(0.92); }

  .menu__item:active, .semana__dia:active { transform: scale(0.95); }

  /* Cartão inteiro: bem pouco, senão parece que a lista toda balança */
  .compromisso:active, .nota:active,
  .tarefa:has(> .tarefa__corpo:active) { transform: scale(0.985); }
}

@media (hover: hover) and (pointer: fine) {
  /* Cartões clicáveis clareiam sob o mouse: avisa "isto abre alguma coisa" */
  .compromisso:hover, .nota:hover,
  .tarefa:has(> .tarefa__corpo:hover) {
    border-color: var(--borda-forte);
    background: var(--superficie-2);
  }
  .menu__item:not([aria-current="page"]):hover { color: var(--texto); background: var(--superficie-2); }
  .filtro:not([aria-pressed="true"]):hover { color: var(--texto); border-color: var(--borda-forte); }
  .aba:not([aria-selected="true"]):hover { color: var(--texto); }
  .semana__dia:not([aria-pressed="true"]):hover { background: var(--superficie-2); }
  .dia-semana:not(:has(input:checked)):hover { border-color: var(--borda-forte); }
  .escolha__estrela:not([aria-pressed="true"]):not(:disabled):hover { color: var(--texto); border-color: var(--borda-forte); }
  .secao__link:hover { text-decoration: underline; }
}

/* ---------------------------------------------------------------------
   3. Troca de tela
   O roteador apaga a tela antiga e coloca a nova dentro de <main id="app">.
   Todo elemento novo ali dentro roda esta animação sozinho, sem JavaScript.
   Ela é curta e sutil porque a gente troca de tela o tempo todo.
   "backwards": antes de começar, o elemento já fica no estado inicial (invisível).
   A <dialog> da Entrada fica de fora: ela tem a animação própria (seção 6).
   --------------------------------------------------------------------- */
#app > :not(dialog) {
  animation: surgir var(--duracao-media) var(--curva-saida) backwards;
}

/* ---------------------------------------------------------------------
   4. Conteúdo que acabou de chegar do banco
   A tela coloca a classe "chegando" só no PRIMEIRO desenho (e ao trocar de
   aba na Agenda). Os redesenhos seguintes (ex.: depois de concluir uma tarefa)
   trocam sem animação; senão a lista inteira "piscaria" a cada clique.
   Cada bloco começa 50ms depois do anterior: o olho acompanha de cima para baixo.
   --------------------------------------------------------------------- */
.chegando > * { animation: surgir var(--duracao-media) var(--curva-saida) backwards; }
.chegando > :nth-child(2) { animation-delay: 50ms; }
.chegando > :nth-child(3) { animation-delay: 100ms; }
.chegando > :nth-child(4) { animation-delay: 150ms; }
.chegando > :nth-child(n + 5) { animation-delay: 200ms; } /* do 5º em diante, juntos: ninguém espera */

/* Mensagem de erro (formulário recusado etc.) chama o olho ao aparecer */
.mensagem--erro { animation: surgir var(--duracao-media) var(--curva-saida) backwards; }

/* ---------------------------------------------------------------------
   5. Esqueleto (componentes/esqueleto.js)
   Cartões "vazios" no formato do conteúdo, enquanto o banco responde.
   Ele só aparece depois de 150ms: se o banco responder antes disso,
   você nem chega a vê-lo (um esqueleto piscando por 50ms incomoda mais).
   --------------------------------------------------------------------- */
.esqueleto {
  display: flex; flex-direction: column; gap: 12px;
  animation: aparecer var(--duracao-media) ease 150ms backwards;
}
.esqueleto__cartao {
  position: relative;
  overflow: hidden; /* o brilho não pode vazar para fora do cartão */
  display: flex; flex-direction: column; gap: 10px;
  padding: 18px 16px;
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--raio);
}
.esqueleto__linha { height: 12px; width: 72%; border-radius: 6px; background: var(--superficie-2); }
.esqueleto__linha--curta { width: 38%; }

@media (prefers-reduced-motion: no-preference) {
  /* Faixa de brilho atravessando o cartão: diz "estou trabalhando".
     Movimento contínuo usa curva linear (velocidade constante). */
  .esqueleto__cartao::after {
    content: "";
    position: absolute; inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.045), transparent);
    transform: translateX(-100%);
    animation: brilho 1.4s linear infinite;
  }
}
@keyframes brilho {
  to { transform: translateX(100%); }
}

/* ---------------------------------------------------------------------
   6. Janelas (<dialog>: editor, captura rápida, classificar)
   Abrem crescendo de 96% (nada no mundo real surge do tamanho zero) e
   o fundo escurece junto. Fecham mais rápido do que abrem: na saída, você
   já decidiu e quer voltar logo para a tela.

   @starting-style diz "de onde partir" quando o elemento acaba de aparecer.
   --------------------------------------------------------------------- */
.janela[open] {
  transition:
    opacity var(--duracao-media) var(--curva-saida),
    transform var(--duracao-media) var(--curva-saida);
}
.janela[open]::backdrop { transition: opacity var(--duracao-media) var(--curva-saida); }

@starting-style {
  .janela[open], .janela[open]::backdrop { opacity: 0; }
}
@media (prefers-reduced-motion: no-preference) {
  @starting-style {
    .janela[open] { transform: translateY(var(--deslocamento)) scale(0.96); }
  }
}

/* Saída animada. Ao fechar, a <dialog> sai da "camada do topo" (a camada acima
   de tudo) e some na hora. A propriedade "overlay" segura ela lá até a animação
   acabar. Só alguns navegadores conhecem "overlay": nos outros, a janela fecha
   na hora, que é melhor do que vê-la desaparecendo fora do lugar. */
@supports (overlay: auto) {
  .janela, .janela::backdrop {
    transition:
      opacity var(--duracao-curta) var(--curva-saida),
      transform var(--duracao-curta) var(--curva-saida),
      overlay var(--duracao-curta) allow-discrete,
      display var(--duracao-curta) allow-discrete;
  }
  .janela:not([open]), .janela:not([open])::backdrop { opacity: 0; }

  @media (prefers-reduced-motion: no-preference) {
    .janela:not([open]) { transform: scale(0.96); }
  }
}

/* ---------------------------------------------------------------------
   7. Aviso (toast)
   Sobe de baixo e desce de volta pelo mesmo caminho: assim fica claro de onde
   ele veio. Usa transition (e não @keyframes) porque um aviso novo pode chegar
   enquanto o anterior ainda está saindo: a transição muda de rumo no meio do
   caminho, sem recomeçar do zero.

   Por que visibility e não display/hidden? display:none não anima. visibility
   esconde do mesmo jeito (some da tela, do teclado e do leitor de tela), mas
   pode esperar a animação acabar antes de valer.
   --------------------------------------------------------------------- */
.aviso {
  opacity: 0;
  visibility: hidden;
  transform: translateY(calc(var(--deslocamento) * 2));
  transition:
    opacity var(--duracao-curta) var(--curva-saida),
    transform var(--duracao-curta) var(--curva-saida),
    visibility 0s linear var(--duracao-curta); /* esconde só DEPOIS de terminar de sumir */
}
.aviso--visivel {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition:
    opacity var(--duracao-media) var(--curva-saida),
    transform var(--duracao-media) var(--curva-saida),
    visibility 0s; /* aparece na hora, para a animação de entrada ser vista */
}

/* ---------------------------------------------------------------------
   8. Abas com indicador que desliza ("Entrar | Criar conta", "Compromissos | Tarefas | Notas")
   Em vez de cada aba ter o próprio fundo, um único "indicador" (::before) anda
   até a aba escolhida. O movimento mostra a mudança de lugar.
   :has() pergunta "existe, dentro de .abas, a 2ª aba selecionada?" e move o
   indicador sem uma linha de JavaScript. Fica dentro de @supports porque, num
   navegador sem :has(), o indicador ficaria parado na 1ª aba.
   --------------------------------------------------------------------- */
@supports selector(:has(*)) {
  .abas {
    position: relative;
    isolation: isolate; /* cria uma "camada" própria: o z-index -1 abaixo fica atrás das abas, mas na frente do fundo */
  }
  .abas::before {
    content: "";
    position: absolute;
    z-index: -1;
    top: 4px; bottom: 4px; left: 4px;
    /* .abas tem 4px de borda interna dos dois lados e 4px entre as abas:
       com 2 abas, cada uma tem (largura - 4 - 4 - 4) / 2 */
    width: calc((100% - 12px) / 2);
    border-radius: 8px;
    background: var(--azul-fundo);
  }
  .abas--tres::before { width: calc((100% - 16px) / 3); }

  /* Dentro do translateX, 100% é a largura do próprio indicador; +4px pula o vão */
  .abas:has(> .aba:nth-child(2)[aria-selected="true"])::before { transform: translateX(calc(100% + 4px)); }
  .abas:has(> .aba:nth-child(3)[aria-selected="true"])::before { transform: translateX(calc(200% + 8px)); }

  /* Quem pinta o fundo agora é o indicador */
  .aba[aria-selected="true"] { background: transparent; }

  @media (prefers-reduced-motion: no-preference) {
    /* Algo que ANDA pela tela usa a curva de movimento (acelera e freia) */
    .abas::before { transition: transform var(--duracao-media) var(--curva-movimento); }
  }
}

/* ---------------------------------------------------------------------
   9. Concluir tarefa (componentes/cartaoTarefa.js)
   É o momento de recompensa do app, então ganha um pouco mais de capricho:
   o círculo dá um "pulinho", o ✓ é desenhado da esquerda para a direita e o
   título ganha o risco. Tudo acontece NA HORA do toque, antes de o banco
   responder (a classe "tarefa--concluindo" é colocada pelo JS no clique).
   --------------------------------------------------------------------- */
.tarefa .item__titulo { transition: color var(--duracao-media) ease; }

.tarefa--concluindo .circulo { background: var(--azul-forte); border-color: var(--azul-forte); }
.tarefa--concluindo .circulo::after { content: "✓"; display: inline-block; }
.tarefa--concluindo .item__titulo {
  color: var(--texto-suave);
  text-decoration: line-through;
  animation: riscar var(--duracao-media) ease backwards;
}

@media (prefers-reduced-motion: no-preference) {
  .tarefa--concluindo .circulo { animation: marcar 320ms var(--curva-saida); }
  /* Começa 60ms depois do pulinho, para as duas coisas não brigarem pelo olho */
  .tarefa--concluindo .circulo::after { animation: desenhar-check var(--duracao-media) var(--curva-saida) 60ms backwards; }
}

/* Em @keyframes, a curva vale para CADA trecho: encolhe, passa um pouco do tamanho e volta */
@keyframes marcar {
  0%   { transform: scale(0.85); }
  55%  { transform: scale(1.1); }
  100% { transform: scale(1); }
}
/* clip-path "recorta" o ✓: começa todo escondido e vai revelando para a direita */
@keyframes desenhar-check {
  from { clip-path: inset(0 100% 0 0); }
}
/* O risco aparece de transparente até a cor do texto */
@keyframes riscar {
  from { text-decoration-color: transparent; }
}

/* ---------------------------------------------------------------------
   10. Faixa da semana (Agenda)
   Ao ir para a próxima semana, os dias novos entram pela direita; ao voltar,
   pela esquerda. É o mesmo gesto de virar uma página: você sabe para onde foi.
   O JS (agenda.js) marca data-direcao só no desenho logo após a troca.
   --------------------------------------------------------------------- */
.semana__dias[data-direcao="frente"] .semana__dia { animation: vir-da-direita var(--duracao-media) var(--curva-saida) backwards; }
.semana__dias[data-direcao="tras"] .semana__dia { animation: vir-da-esquerda var(--duracao-media) var(--curva-saida) backwards; }

/* ---------------------------------------------------------------------
   11. Revisão Semanal
   --------------------------------------------------------------------- */

/* Barra de passos: o azul corre da esquerda para a direita ao avançar.
   scaleX anima a largura sem recalcular o layout (width recalcularia). */
.revisao__barra span { position: relative; overflow: hidden; }
.revisao__barra span::after {
  content: "";
  position: absolute; inset: 0;
  background: var(--azul);
  transform: scaleX(0);
  transform-origin: left; /* cresce a partir da esquerda, não do meio */
}
.revisao__barra span.feito::after { transform: scaleX(1); }

/* Passos: o próximo entra pela direita, o anterior volta pela esquerda (revisao.js) */
.revisao__corpo[data-direcao="frente"] > * { animation: vir-da-direita var(--duracao-media) var(--curva-saida) backwards; }
.revisao__corpo[data-direcao="tras"] > * { animation: vir-da-esquerda var(--duracao-media) var(--curva-saida) backwards; }

@media (prefers-reduced-motion: no-preference) {
  .revisao__barra span::after { transition: transform var(--duracao-media) var(--curva-movimento); }

  /* Gráfico da semana: as barras crescem do zero, uma depois da outra.
     Pode ser mais lento que o resto (500ms): acontece uma vez por semana e
     explica o dado ("cada barra é um dia"). --ordem vem do revisao.js. */
  .grafico__barra {
    transform-origin: bottom;
    animation: crescer 500ms var(--curva-saida) backwards;
    animation-delay: calc(120ms + var(--ordem, 0) * 50ms);
  }
  /* O número em cima da barra só aparece quando ela termina de crescer
     (dentro da barra, ele seria esticado junto) */
  .grafico__valor {
    animation: aparecer var(--duracao-curta) ease backwards;
    animation-delay: calc(450ms + var(--ordem, 0) * 50ms);
  }
}
@keyframes crescer {
  from { transform: scaleY(0); }
}
