/* =============================================================================
   SuperRico Workspace — animações (ESPEC §5.4). 100% CSS, nenhuma em JavaScript.
   Todas respeitam @media (prefers-reduced-motion: reduce) no fim do arquivo.
   ============================================================================= */

/* --- fade-slide-in: entrada de cards/seções, escalonada via --i --------------- */
@keyframes sr-fade-slide-in {
  from { opacity: 0; transform: translateY(.75rem); }
  to   { opacity: 1; transform: none; }
}

.fade-slide-in {
  animation: sr-fade-slide-in .32s ease-out both;
  animation-delay: calc(var(--i, 0) * 60ms);
}


/* --- escalonamento do fade-slide-in sem style inline (CSP §8.5) --------------- */
.i-1 { --i: 1; }
.i-2 { --i: 2; }
.i-3 { --i: 3; }
.i-4 { --i: 4; }
.i-5 { --i: 5; }
.i-6 { --i: 6; }
.i-7 { --i: 7; }
.i-8 { --i: 8; }
.i-9 { --i: 9; }
.i-10 { --i: 10; }
.i-11 { --i: 11; }
.i-12 { --i: 12; }

/* --- campo-salvo: halo verde no input após o autosave (§4.3) ------------------ */
.campo-salvo {
  box-shadow: 0 0 0 .2rem var(--verde-300);
  transition: box-shadow .25s ease-in-out;
}

/* --- fk-highlight: destaca o campo de origem ao chegar pela Curva ------------- */
@keyframes sr-fk-highlight {
  0%, 100% { outline-color: transparent; }
  50%      { outline-color: var(--verdeMedio); }
}

.fk-highlight {
  outline: 3px solid transparent;
  outline-offset: 2px;
  border-radius: var(--sr-raio);
  animation: sr-fk-highlight 2.5s ease-in-out 1;
}

/* --- barra-progresso: MUDOU DE ARQUIVO EM 14/09/2026 ---------------------------
   ⚠️ AS DUAS REGRAS SAÍRAM DAQUI, e a saída é o conserto de um defeito que durou
   meses: a do preenchimento era `.barra-progresso > .barra-progresso-valor`, com
   `inline-size: 0`. Dois seletores de classe vencem o `.pct-45` do `site.css`, que
   tem um só — então TODA barra do sistema calculava largura zero e nunca aparecia,
   com o Razor escrevendo a classe certa o tempo todo.

   Agora as duas moram no `site.css`, imediatamente antes das `.pct-*`: mesma
   especificidade, e quem vence é a ordem. Barra de progresso é componente, não
   animação — aqui ficou só o que é movimento, logo abaixo, no bloco de
   `prefers-reduced-motion`. */

/* --- skeleton: carregamento de listas via AJAX -------------------------------- */
@keyframes sr-skeleton {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

.skeleton {
  background-image: linear-gradient(90deg, var(--linha) 25%, var(--verde-050) 37%, var(--linha) 63%);
  background-size: 400% 100%;
  animation: sr-skeleton 1.4s ease-in-out infinite;
  border-radius: var(--sr-raio);
  color: transparent;
  user-select: none;
}

/* --- toast: confirmações e erros ---------------------------------------------- */
@keyframes sr-toast-in {
  from { opacity: 0; transform: translateY(1rem); }
  to   { opacity: 1; transform: none; }
}

.sr-toast {
  animation: sr-toast-in .24s ease-out both;
  transition: opacity .24s ease, transform .24s ease;
}

.sr-toast.saindo {
  opacity: 0;
  transform: translateY(1rem);
}

/* ⚠️ O AVISO DE PROCESSO NÃO PODE DEPENDER DA ANIMAÇÃO PARA EXISTIR.
   -----------------------------------------------------------------------------
   O `sr-toast-in` acima começa em `opacity: 0`. Enquanto a animação roda, tudo
   bem; onde ela NÃO roda, o aviso fica invisível para sempre — e "não roda" não é
   hipótese de laboratório: o Chromium congela animação e `requestAnimationFrame`
   em aba oculta (medido em 01/09/2026: `currentTime` parado em 0 depois de um
   segundo), e o autosave grava justamente no `visibilitychange`. Basta um motor,
   uma extensão ou um estado de janela que suspenda a animação para o "Salvando…"
   sumir sem deixar nada no console.

   Um indicador de estado não pode ter a própria visibilidade dependendo de um
   efeito decorativo. Aqui ele nasce OPACO e a animação só o desliza — se ela não
   rodar, perde-se o deslize, não a mensagem.

   Mais específico que `.sr-toast` de propósito: esta folha carrega depois da
   `site.css`, e sem a segunda classe a regra de cima venceria de volta.
   ----------------------------------------------------------------------------- */
@keyframes sr-pilula-entra {
  from { transform: translateY(.75rem); }
}

.sr-toast.sr-toast-processo {
  opacity: 1;
  animation: sr-pilula-entra .18s ease-out;
}

/* --- Kanban do CRM: arraste de cards entre estágios (§7.3) --------------------- */
.kanban-card {
  transition: transform .18s ease, box-shadow .18s ease;
  cursor: grab;
}

.kanban-card:active { cursor: grabbing; }

.kanban-card.arrastando {
  transform: rotate(1.5deg) scale(1.02);
  box-shadow: 0 .5rem 1rem rgb(0 0 0 / .15);
}

.kanban-coluna.sobre {
  background-color: var(--verde-050);
  transition: background-color .18s ease;
}

/* --- a Curva de Vitalidade do véu do login (§8.1) ------------------------------
   Cada barra sobe da linha de base, fica de pé por um tempo e recolhe; o atraso de
   cada uma vem do seu índice, e é esse atraso que transforma 56 barras subindo em
   UMA curva sendo traçada da esquerda para a direita.

   ⚠️ O ÍNDICE CHEGA NO `--sr-i`, ESCRITO PELO SERVIDOR. Não dá para usar as
   utilitárias `.i-1`…`.i-12` daqui de cima: são 56 barras, e o escalonamento aqui
   é geometria do desenho, não ordem de entrada de cartões.

   ⚠️ `transform-box: fill-box` É O QUE FAZ A BARRA CRESCER DO CHÃO. Sem ele a
   origem do `transform` num elemento SVG é o canto do `viewBox`, e as barras
   encolheriam na direção do topo da caixa — a curva desabaria para cima. Com ele,
   `bottom` é a base da própria barra, que é a linha de base do gráfico. */
@keyframes sr-carregando-sobe {
  0%   { transform: scaleY(.02); opacity: 0; }
  6%   { opacity: 1; }
  18%  { transform: scaleY(1);   opacity: 1; }
  50%  { transform: scaleY(1);   opacity: 1; }
  68%  { transform: scaleY(.02); opacity: 0; }
  100% { transform: scaleY(.02); opacity: 0; }
}

.sr-carregando-barra {
  --sr-carregando-ciclo: 2.6s;
  --sr-carregando-passo: .014s;

  transform-box: fill-box;
  transform-origin: bottom;
  animation: sr-carregando-sobe var(--sr-carregando-ciclo) cubic-bezier(.16,.84,.32,1) infinite;
  animation-delay: calc(var(--sr-i, 0) * var(--sr-carregando-passo));
  will-change: transform, opacity;
}


/* =============================================================================
   Acessibilidade — ESPEC §5.4 e DoD §11.4 item 3.
   ============================================================================= */
@media (prefers-reduced-motion: reduce) {
  .fade-slide-in,
  .skeleton,
  .sr-toast,
  .fk-highlight {
    animation: none !important;
  }

  /* Sem animação o aviso continua opaco — a regra de opacidade acima é dele, não
     da animação, e é isso que garante que ele apareça aqui também. */

  .campo-salvo,
  .sr-toast,
  .kanban-card,
  .kanban-coluna.sobre,
  /* O FAB do §7.5 cresce e sobe no hover desde 01/09/2026 — movimento é movimento,
     mesmo o de um botão. Ele continua mudando de sombra, que não é deslocamento. */
  .sr-widget-botao {
    transition: none !important;
  }

  /* E, sem transição, o `transform` do hover viraria um salto seco. Some com ele. */
  .sr-widget-botao:hover,
  .sr-widget-botao:focus-visible {
    transform: none;
  }

  .fk-highlight { outline-color: var(--verdeMedio); }

  /* ⚠️ A CURVA DO LOGIN NÃO ENTRA NA LISTA DO `animation: none` acima, e a razão é a
     mesma do aviso de processo: ela é um INDICADOR DE ESTADO. Parada, vira um
     gráfico bonito e mudo, e a pessoa fica olhando para uma tela que não diz se
     ainda está trabalhando. O que incomoda em `reduce` é deslocamento, não
     luminosidade — então o movimento sai e fica a respiração: a curva aparece
     inteira, de pé, pulsando de leve. Sem `transform` nenhum. */
  .sr-carregando-barra {
    animation: sr-carregando-respira 2.4s ease-in-out infinite;
    transform: none;
  }
}

@keyframes sr-carregando-respira {
  0%, 100% { opacity: .45; }
  50%      { opacity: 1; }
}
