/* ============================================================
   movimento.css — Linguagem de interação (Fase 7)

   Camada de fundação do movimento da plataforma. Contém:
   1. tokens de tempo, curva e deslocamento;
   2. keyframes canônicos de entrada e saída;
   3. classes utilitárias aplicadas por movimento.js;
   4. componentes novos que só existem por causa desta camada
      (notificações, esqueleto de carregamento, indicador de aba);
   5. um único bloco `prefers-reduced-motion`.

   Carregado ANTES de styles.css, para que os tokens estejam
   disponíveis a todas as regras do sistema.

   REGRAS DESTE ARQUIVO
   - Só se anima `transform`, `opacity`, `clip-path` e
     `grid-template-rows`. Nada que force recálculo de layout.
   - Saída é sempre a entrada invertida e mais rápida (~65%).
   - Nenhuma duração acima de --mov-4, exceto valores numéricos
     (--mov-5), onde a duração comunica "calculando".
   ============================================================ */

:root {
  /* Tempo */
  --mov-1: 90ms;   /* micro-resposta: pressionar, hover de ícone            */
  --mov-2: 160ms;  /* troca de estado no lugar; saída de elemento local     */
  --mov-3: 240ms;  /* entrada/saída local: linha, painel, notificação       */
  --mov-4: 320ms;  /* camadas: modal, ficha, seção inteira                  */
  --mov-5: 480ms;  /* valores: anel de progresso, barras, contadores        */

  /* Curvas */
  --curva-saida: cubic-bezier(.22, .61, .36, 1);    /* entrada — desacelera */
  --curva-entrada: cubic-bezier(.55, .06, .68, .19);/* saída — acelera      */
  --curva-mov: cubic-bezier(.65, 0, .35, 1);        /* entre duas posições  */
  --curva-confirma: cubic-bezier(.34, 1.24, .64, 1);/* só confirmação       */

  /* Deslocamento de entrada */
  --desl-1: 4px;
  --desl-2: 8px;
  --desl-3: 14px;
}

/* ============================================================
   1. Keyframes canônicos
   ============================================================ */

@keyframes mov-fade-ent { from { opacity: 0 } to { opacity: 1 } }
@keyframes mov-fade-sai { from { opacity: 1 } to { opacity: 0 } }

@keyframes mov-camada-ent {
  from { opacity: 0; transform: scale(.965) translateY(var(--desl-2)) }
  to   { opacity: 1; transform: none }
}
@keyframes mov-camada-sai {
  from { opacity: 1; transform: none }
  to   { opacity: 0; transform: scale(.978) }
}

@keyframes mov-linha-ent {
  from { opacity: 0; transform: translateY(calc(var(--desl-2) * -1)) }
  to   { opacity: 1; transform: none }
}
@keyframes mov-linha-sai {
  from { opacity: 1; transform: none }
  to   { opacity: 0; transform: translateX(var(--desl-3)) }
}

@keyframes mov-card-ent {
  from { opacity: 0; transform: translateY(var(--desl-3)) scale(.985) }
  to   { opacity: 1; transform: none }
}

@keyframes mov-desce {
  from { opacity: 0; transform: translateY(calc(var(--desl-1) * -1)) }
  to   { opacity: 1; transform: none }
}

@keyframes mov-notif-ent {
  from { opacity: 0; transform: translateY(var(--desl-3)) scale(.97) }
  to   { opacity: 1; transform: none }
}
@keyframes mov-notif-sai {
  from { opacity: 1; transform: none }
  to   { opacity: 0; transform: translateY(var(--desl-2)) scale(.98) }
}

@keyframes mov-pane-esq {
  from { opacity: 0; transform: translateX(var(--desl-3)) }
  to   { opacity: 1; transform: none }
}
@keyframes mov-pane-dir {
  from { opacity: 0; transform: translateX(calc(var(--desl-3) * -1)) }
  to   { opacity: 1; transform: none }
}

@keyframes mov-pulso {
  0%   { transform: scale(1) }
  45%  { transform: scale(1.04) }
  100% { transform: scale(1) }
}

@keyframes mov-gira { to { transform: rotate(360deg) } }
@keyframes mov-brilho { to { transform: translateX(100%) } }

/* ============================================================
   2. Classes utilitárias (aplicadas por movimento.js)
   ============================================================ */

.mov-ent    { animation: mov-linha-ent var(--mov-3) var(--curva-saida) both }
.mov-sai    { animation: mov-linha-sai var(--mov-2) var(--curva-entrada) both }
.mov-painel { animation: mov-desce var(--mov-3) var(--curva-saida) both }
.mov-pulso  { animation: mov-pulso var(--mov-4) var(--curva-confirma) }

/* Entrada escalonada. O atraso vem por CSSOM (--atraso), nunca por
   atributo style="..." — a CSP não admite estilo inline (D020). */
.mov-stagger {
  animation: mov-card-ent var(--mov-4) var(--curva-saida) both;
  animation-delay: var(--atraso, 0ms);
}

/* Painéis de aba: a direção do deslize diz para onde o usuário foi. */
.mov-pane-esq { animation: mov-pane-esq var(--mov-3) var(--curva-saida) both }
.mov-pane-dir { animation: mov-pane-dir var(--mov-3) var(--curva-saida) both }

/* Suprime a animação de um elemento por um frame (usado ao posicionar
   o indicador de aba pela primeira vez, para ele não deslizar do zero). */
.mov-sem-anim, .mov-sem-anim * {
  animation: none !important;
  transition: none !important;
}

/* ============================================================
   3. Camadas (overlays)

   O estado `fechando` mantém o overlay visível enquanto a animação
   de saída roda; movimento.js só remove a classe quando a animação
   termina. É isso que impede o "elemento que simplesmente some".
   ============================================================ */

.overlay.fechando { display: flex; pointer-events: none }

.overlay.open      { animation: mov-fade-ent var(--mov-2) var(--curva-saida) both }
.overlay.fechando  { animation: mov-fade-sai var(--mov-2) var(--curva-entrada) both }

.overlay.open > .modal     { animation: mov-camada-ent var(--mov-4) var(--curva-saida) both }
.overlay.fechando > .modal { animation: mov-camada-sai var(--mov-2) var(--curva-entrada) both }

/* O desfoque de fundo é o efeito mais caro da aplicação (A-10).
   Ele é aplicado por movimento.js SÓ depois que a animação de
   entrada termina, e nunca sob prefers-reduced-motion. */
.overlay.desfoque { backdrop-filter: blur(3px) }

/* ============================================================
   4. Notificações (substituem o #toast único)

   Fila empilhada, com variante semântica e região aria-live.
   ============================================================ */

.notificacoes {
  position: fixed;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 200;
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 8px;
  pointer-events: none;
  max-width: min(560px, calc(100vw - 32px));
}
.notif {
  display: flex;
  align-items: center;
  gap: 9px;
  background: var(--navy);
  color: #fff;
  padding: 12px 20px;
  border-radius: 12px;
  font-weight: 700;
  font-size: 13px;
  line-height: 1.4;
  box-shadow: 0 14px 34px rgba(0, 0, 0, .35);
  border-left: 4px solid var(--orange);
  pointer-events: auto;
  animation: mov-notif-ent var(--mov-3) var(--curva-saida) both;
}
.notif.saindo { animation: mov-notif-sai var(--mov-2) var(--curva-entrada) both }
.notif svg { width: 16px; height: 16px; flex: none }
.notif-ok   { border-left-color: var(--green) }
.notif-ok svg { color: var(--green) }
.notif-erro { border-left-color: var(--red) }
.notif-erro svg { color: var(--red) }
.notif-aviso { border-left-color: var(--orange) }
.notif-aviso svg { color: var(--orange) }

/* ============================================================
   5. Estado ocupado / concluído em botões de ação assíncrona

   Resolve A-05: entre o clique e a resposta da API o controle
   passa a comunicar que está trabalhando, e recusa o segundo
   clique.
   ============================================================ */

.btn[data-ocupado], .btn[data-concluido] { pointer-events: none }
.btn[data-ocupado] { opacity: .85; cursor: progress }
.btn[data-concluido] { background: var(--green); color: #fff }
.btn-ghost[data-concluido] { border-color: var(--green) }

.mov-spin {
  width: 14px;
  height: 14px;
  flex: none;
  border: 2px solid rgba(255, 255, 255, .4);
  border-top-color: #fff;
  border-radius: 50%;
  animation: mov-gira .7s linear infinite;
}
.btn-ghost .mov-spin {
  border-color: rgba(14, 42, 71, .25);
  border-top-color: var(--navy);
}

/* ============================================================
   6. Esqueleto de carregamento
   ============================================================ */

.esqueleto {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--raio);
  padding: 18px;
  position: relative;
  overflow: hidden;
  min-height: 210px;
}
.esqueleto i {
  display: block;
  height: 10px;
  border-radius: 99px;
  background: var(--border);
  margin-bottom: 10px;
  opacity: .8;
}
.esqueleto i:nth-child(1) { width: 55% }
.esqueleto i:nth-child(2) { width: 85% }
.esqueleto i:nth-child(3) { width: 70% }
.esqueleto i:nth-child(4) { width: 90% }
.esqueleto i:nth-child(5) { width: 40% }
.esqueleto::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(232, 120, 26, .10), transparent);
  transform: translateX(-100%);
  animation: mov-brilho 1.15s infinite;
}

/* ============================================================
   7. Indicador deslizante das abas de Estrutura

   Posição e largura vêm por CSSOM (--aba-x / --aba-w).
   ============================================================ */

.aba-ind {
  position: absolute;
  top: 3px;
  bottom: 3px;
  left: 0;
  width: var(--aba-w, 0);
  transform: translateX(var(--aba-x, 0));
  background: var(--orange);
  border-radius: 7px;
  box-shadow: 0 2px 6px rgba(232, 120, 26, .25);
  transition: transform var(--mov-3) var(--curva-mov), width var(--mov-3) var(--curva-mov);
  pointer-events: none;
}

/* ============================================================
   8. Redução de movimento

   Deslocamento vira instantâneo; o feedback continua existindo.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  .overlay.desfoque { backdrop-filter: none }
  .esqueleto::after { display: none }
}
