/*
 * =====================================================================
 * SAFIEDESK — Camada de micro-animação de ícones
 * static/css/icon-motion.css
 *
 * Por que este arquivo mira o NOME do ícone
 * -----------------------------------------
 * 131 pontos do repositório reescrevem a classe do ícone em tempo de
 * execução — 28 por `elem.className = 'fas fa-x'` e 103 dentro de
 * `innerHTML`. Uma classe de animação pintada à mão no markup morre em
 * todos eles: `base_cliente.html` faz
 * `icon.className = 'fas fa-sun theme-icon'` e apaga o que estivesse lá.
 * Uma regra `.fa-sun { ... }` sobrevive.
 *
 * O mesmo vale para o backend: `utils/historico.py` grava `icon='sync'`
 * no Mongo e o front prefixa `fas fa-`. Mirar o nome cobre esses 32
 * nomes sem tocar em Python nem no contrato de dados.
 *
 * Precedente da casa: `static/css/ticket_detalhe.css` já fazia
 * `.btn-save .fa-spinner { animation: spin ... }`. Esta camada
 * generaliza aquilo.
 *
 * Escopo por perfil
 * -----------------
 * `<body data-motion-profile="cliente">`   layouts/base_cliente.html
 * `<body data-motion-profile="consultor">` layouts/base.html
 *
 * A área do cliente tem telas de feedback; a do consultor tem tabelas
 * densas, onde movimento repetido vira ruído. Por isso `fa-times` e
 * `fa-check` — os dois nomes de maior massa — só animam no cliente.
 *
 * Como escolher se um ícone anima
 * -------------------------------
 * Pela FUNÇÃO, não pela aparência: anima o que significa movimento ou
 * mudança de estado (carregando, sincronizando, notificação nova,
 * upload, sucesso/erro, seta de CTA). Não anima rótulo: cabeçalho de
 * tabela, label de campo, marcador de linha, breadcrumb, chevron.
 *
 * Fora de alcance, documentado
 * ----------------------------
 * Dois ícones vêm de pseudo-elemento e nenhuma regra `.fa-*` os atinge:
 * `ticket_detalhe.css` (`::after` com \f0d7) e `.priority-badge::before`.
 *
 * Escape: `.no-motion` no próprio ícone ou em qualquer ancestral.
 *
 * =====================================================================
 * @@MOTION-MANIFEST
 * Fonte de verdade única. `scripts/frontend/relatorio_motion_icones.py`
 * lê este bloco; não mantenha uma segunda lista em lugar nenhum.
 *
 * tier1: fa-spinner fa-circle-notch fa-sync fa-sync-alt fa-rotate
 *        fa-rotate-right fa-rotate-left fa-redo fa-redo-alt fa-undo
 *        fa-arrows-rotate fa-bell fa-bell-slash fa-upload fa-download
 *        fa-cloud-upload-alt fa-cloud-download-alt fa-file-upload
 *        fa-file-download
 *
 * tier2: fa-check-circle fa-circle-check fa-times-circle fa-circle-xmark
 *        fa-exclamation-triangle fa-triangle-exclamation
 *        fa-exclamation-circle fa-circle-exclamation fa-info-circle
 *        fa-ban fa-arrow-right fa-arrow-up fa-arrow-down fa-paper-plane
 *        fa-save fa-floppy-disk fa-plus fa-plus-circle fa-play fa-pause
 *        fa-play-circle fa-pause-circle
 *
 * tier2-cliente-only: fa-times fa-xmark fa-check
 *
 * tier3-cliente: fa-arrow-left fa-external-link-alt
 *        fa-arrow-up-right-from-square fa-paperclip fa-clock
 *        fa-user-clock fa-trash fa-trash-alt fa-heart fa-star fa-magic
 *        fa-robot fa-rocket fa-bolt fa-comment fa-comments
 *        fa-comment-dots fa-calendar-check fa-calendar-plus fa-flag
 *        fa-flag-checkered fa-eye fa-eye-slash fa-lock fa-lock-open
 *        fa-unlock fa-link fa-unlink fa-user-plus fa-user-check
 *        fa-user-minus fa-copy fa-share-nodes fa-sign-out-alt
 *        fa-life-ring fa-lightbulb fa-medal fa-crown
 * @@
 * =====================================================================
 */

/* =====================================================================
   VOCABULÁRIO
   Prefixo safie- obrigatório: `spin` já existe 9x e `pulse` 12x no repo,
   e um @keyframes de mesmo nome declarado depois vence em silêncio.
   Só transform / opacity / clip-path — nada que force layout.
   ===================================================================== */
@keyframes safie-spin    { to { transform: rotate(360deg); } }

@keyframes safie-pop {
  0%   { transform: scale(.6); opacity: 0; }
  60%  { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Substituto possível para o "desenho de traço" do heroicons-animated:
   Font Awesome aqui é WEBFONT, e glifo de fonte não tem stroke para animar.
   O wipe por clip-path é o mais próximo sem trocar o FA para modo SVG. */
@keyframes safie-reveal {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0); }
}

@keyframes safie-ring {
  0%, 100% { transform: rotate(0); }
  20%      { transform: rotate(-12deg); }
  45%      { transform: rotate(10deg); }
  70%      { transform: rotate(-6deg); }
}

@keyframes safie-nudge  { 50% { transform: translateX(3px); } }
@keyframes safie-lift   { 50% { transform: translateY(-3px); } }
@keyframes safie-sink   { 50% { transform: translateY(3px); } }

@keyframes safie-breathe {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .45; transform: scale(.96); }
}

:root {
  --motion-loop-spin:    900ms linear;
  --motion-loop-breathe: 1600ms ease-in-out;
  --motion-ring:         700ms cubic-bezier(.36, .07, .19, .97);
}

/* Guarda usada em toda regra de loop: o Font Awesome já traz fa-spin,
   fa-pulse, fa-beat etc. Sem isto o ícone anima duas vezes, e
   `dash_cliente.html` injeta exatamente `fa-spinner fa-pulse`. */

/* =====================================================================
   TIER 1 — vale nos dois perfis
   ===================================================================== */
[data-motion-profile] .fa-spinner:not(.fa-spin):not(.fa-pulse):not(.fa-spin-pulse),
[data-motion-profile] .fa-circle-notch:not(.fa-spin):not(.fa-pulse):not(.fa-spin-pulse) {
  animation: safie-spin var(--motion-loop-spin) infinite;
}

/* Sincronização: gira só enquanto a ação está em curso (.is-loading no
   botão ou no container), para não virar ruído numa barra de ferramentas. */
[data-motion-profile] .is-loading > .fa-sync,
[data-motion-profile] .is-loading > .fa-sync-alt,
[data-motion-profile] .is-loading > .fa-rotate,
[data-motion-profile] .is-loading > .fa-arrows-rotate,
[data-motion-profile] .is-loading > .fa-redo,
[data-motion-profile] .is-loading > .fa-redo-alt {
  animation: safie-spin var(--motion-loop-spin) infinite;
}
/* Em repouso, giram um quarto de volta no hover do botão */
[data-motion-profile] .btn:hover > .fa-sync,
[data-motion-profile] .btn:hover > .fa-sync-alt,
[data-motion-profile] .btn:hover > .fa-rotate,
[data-motion-profile] .btn:hover > .fa-arrows-rotate,
[data-motion-profile] .btn:hover > .fa-redo,
[data-motion-profile] .btn:hover > .fa-redo-alt,
[data-motion-profile] .btn:hover > .fa-rotate-left,
[data-motion-profile] .btn:hover > .fa-rotate-right,
[data-motion-profile] .btn:hover > .fa-undo {
  transform: rotate(90deg);
}
[data-motion-profile] .fa-sync, [data-motion-profile] .fa-sync-alt,
[data-motion-profile] .fa-rotate, [data-motion-profile] .fa-arrows-rotate,
[data-motion-profile] .fa-redo, [data-motion-profile] .fa-redo-alt,
[data-motion-profile] .fa-rotate-left, [data-motion-profile] .fa-rotate-right,
[data-motion-profile] .fa-undo {
  transition: transform var(--transition-base, 250ms ease);
}

/* Sino: só balança quando HÁ algo novo. Sino parado é rótulo. */
[data-motion-profile] .has-unread .fa-bell,
[data-motion-profile] [data-unread="true"] .fa-bell,
[data-motion-profile] .fa-bell.has-unread {
  animation: safie-ring var(--motion-ring) 2;
  transform-origin: 50% 10%;
}

/* Transferência de arquivo: sobe no envio, desce no recebimento */
[data-motion-profile] .btn:hover > .fa-upload,
[data-motion-profile] .btn:hover > .fa-cloud-upload-alt,
[data-motion-profile] .btn:hover > .fa-file-upload,
[data-motion-profile] .is-loading > .fa-upload {
  animation: safie-lift var(--transition-base, 250ms ease);
}
[data-motion-profile] .btn:hover > .fa-download,
[data-motion-profile] .btn:hover > .fa-cloud-download-alt,
[data-motion-profile] .btn:hover > .fa-file-download,
[data-motion-profile] .is-loading > .fa-download {
  animation: safie-sink var(--transition-base, 250ms ease);
}

/* Ampulheta: ESTATICA, por decisao do usuario em 07/09/2026.
   Ela aparece em card de contador do dashboard ("Em aprovacao"), onde um
   loop infinito e ruido e nao informacao. Mantida no manifesto como
   tier1 apenas para o relatorio de razao continuar coerente; se voltar a
   animar algum dia, tem de ser sob estado (.is-loading), nao em repouso. */

/* =====================================================================
   TIER 2 — feedback e chamada para ação, nos dois perfis
   ===================================================================== */
[data-motion-profile] .fa-check-circle,
[data-motion-profile] .fa-circle-check,
[data-motion-profile] .fa-times-circle,
[data-motion-profile] .fa-circle-xmark,
[data-motion-profile] .fa-exclamation-triangle,
[data-motion-profile] .fa-triangle-exclamation,
[data-motion-profile] .fa-exclamation-circle,
[data-motion-profile] .fa-circle-exclamation,
[data-motion-profile] .fa-info-circle,
[data-motion-profile] .fa-ban,
[data-motion-profile] .fa-plus-circle,
[data-motion-profile] .fa-play-circle,
[data-motion-profile] .fa-pause-circle {
  animation: safie-pop var(--transition-spring, 400ms cubic-bezier(.34, 1.56, .64, 1)) both;
}

/* Seta de CTA e envio: cutucam no hover do botão */
[data-motion-profile] .btn:hover > .fa-arrow-right,
[data-motion-profile] .btn:hover > .fa-paper-plane,
[data-motion-profile] .btn:focus-visible > .fa-arrow-right,
[data-motion-profile] .btn:focus-visible > .fa-paper-plane {
  animation: safie-nudge var(--transition-base, 250ms ease);
}
[data-motion-profile] .btn:hover > .fa-arrow-up,
[data-motion-profile] .btn:hover > .fa-save,
[data-motion-profile] .btn:hover > .fa-floppy-disk,
[data-motion-profile] .btn:hover > .fa-plus {
  animation: safie-lift var(--transition-base, 250ms ease);
}
[data-motion-profile] .btn:hover > .fa-arrow-down {
  animation: safie-sink var(--transition-base, 250ms ease);
}

/* =====================================================================
   TIER 2 — só CLIENTE
   fa-times (123 no repo) e fa-check (70) são os dois nomes de maior
   massa. No consultor eles aparecem em tabela densa, onde fechar e
   confirmar são ação repetida, não feedback: animar ali vira ruído.
   Excluí-los do perfil consultor é o que leva a razão de 41% para ~25%.
   ===================================================================== */
[data-motion-profile="cliente"] .fa-times,
[data-motion-profile="cliente"] .fa-xmark {
  transition: transform var(--transition-fast, 150ms ease);
}
[data-motion-profile="cliente"] button:hover > .fa-times,
[data-motion-profile="cliente"] button:hover > .fa-xmark,
[data-motion-profile="cliente"] .btn:hover > .fa-times,
[data-motion-profile="cliente"] .btn:hover > .fa-xmark {
  transform: rotate(90deg);
}
[data-motion-profile="cliente"] .fa-check {
  animation: safie-reveal var(--transition-base, 250ms ease) both;
}

/* =====================================================================
   TIER 3 — só CLIENTE
   ===================================================================== */
[data-motion-profile="cliente"] .fa-heart,
[data-motion-profile="cliente"] .fa-star,
[data-motion-profile="cliente"] .fa-medal,
[data-motion-profile="cliente"] .fa-crown,
[data-motion-profile="cliente"] .fa-magic,
[data-motion-profile="cliente"] .fa-robot,
[data-motion-profile="cliente"] .fa-rocket,
[data-motion-profile="cliente"] .fa-bolt,
[data-motion-profile="cliente"] .fa-lightbulb,
[data-motion-profile="cliente"] .fa-life-ring,
[data-motion-profile="cliente"] .fa-calendar-check,
[data-motion-profile="cliente"] .fa-calendar-plus,
[data-motion-profile="cliente"] .fa-user-plus,
[data-motion-profile="cliente"] .fa-user-check,
[data-motion-profile="cliente"] .fa-user-minus,
[data-motion-profile="cliente"] .fa-flag,
[data-motion-profile="cliente"] .fa-flag-checkered,
[data-motion-profile="cliente"] .fa-comment,
[data-motion-profile="cliente"] .fa-comments,
[data-motion-profile="cliente"] .fa-comment-dots {
  animation: safie-pop var(--transition-spring, 400ms cubic-bezier(.34, 1.56, .64, 1)) both;
}

[data-motion-profile="cliente"] .fa-arrow-left,
[data-motion-profile="cliente"] .fa-external-link-alt,
[data-motion-profile="cliente"] .fa-arrow-up-right-from-square,
[data-motion-profile="cliente"] .fa-paperclip,
[data-motion-profile="cliente"] .fa-clock,
[data-motion-profile="cliente"] .fa-user-clock,
[data-motion-profile="cliente"] .fa-trash,
[data-motion-profile="cliente"] .fa-trash-alt,
[data-motion-profile="cliente"] .fa-eye,
[data-motion-profile="cliente"] .fa-eye-slash,
[data-motion-profile="cliente"] .fa-lock,
[data-motion-profile="cliente"] .fa-lock-open,
[data-motion-profile="cliente"] .fa-unlock,
[data-motion-profile="cliente"] .fa-link,
[data-motion-profile="cliente"] .fa-unlink,
[data-motion-profile="cliente"] .fa-copy,
[data-motion-profile="cliente"] .fa-share-nodes,
[data-motion-profile="cliente"] .fa-sign-out-alt {
  transition: transform var(--transition-fast, 150ms ease);
}
[data-motion-profile="cliente"] .btn:hover > .fa-arrow-left {
  transform: translateX(-3px);
}
[data-motion-profile="cliente"] .btn:hover > .fa-paperclip,
[data-motion-profile="cliente"] .btn:hover > .fa-copy,
[data-motion-profile="cliente"] .btn:hover > .fa-link,
[data-motion-profile="cliente"] .btn:hover > .fa-unlink,
[data-motion-profile="cliente"] .btn:hover > .fa-eye,
[data-motion-profile="cliente"] .btn:hover > .fa-eye-slash,
[data-motion-profile="cliente"] .btn:hover > .fa-trash,
[data-motion-profile="cliente"] .btn:hover > .fa-trash-alt,
[data-motion-profile="cliente"] .btn:hover > .fa-external-link-alt,
[data-motion-profile="cliente"] .btn:hover > .fa-arrow-up-right-from-square,
[data-motion-profile="cliente"] .btn:hover > .fa-share-nodes,
[data-motion-profile="cliente"] .btn:hover > .fa-sign-out-alt {
  transform: scale(1.12);
}

/* =====================================================================
   TRAVAS DE CONTEXTO
   Vencem por especificidade e por vir depois. Um ícone com nome "de
   ação" que por acaso está num rótulo não pode animar.
   ===================================================================== */
[data-motion-profile] table i,
[data-motion-profile] thead i,
[data-motion-profile] th i,
[data-motion-profile] .breadcrumb i,
[data-motion-profile] .form-label i,
[data-motion-profile] label i,
[data-motion-profile] .seg-item i,
[data-motion-profile] .pager-item i,
[data-motion-profile] .badge i,
[data-motion-profile] .tag i,
[data-motion-profile] optgroup i,
[data-motion-profile] .no-motion i,
[data-motion-profile] i.no-motion {
  animation: none !important;
  transition: none !important;
  transform: none !important;
}

/* Teto para lista longa: em tabela ou lista, só os 3 primeiros respiram.
   Sem isto, 40 tickets "aguardando" viram 40 animações simultâneas. */
[data-motion-profile] tbody tr:nth-child(n+4) i,
[data-motion-profile] .atendimentos-grid > *:nth-child(n+4) i,
[data-motion-profile] .tickets-grid > *:nth-child(n+4) i,
[data-motion-profile] .lista-tickets > *:nth-child(n+4) i {
  animation: none;
}

/* =====================================================================
   ACESSIBILIDADE
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  [data-motion-profile] i,
  [data-motion-profile] .fa,
  [data-motion-profile] svg.svg-inline--fa {
    animation: none !important;
    transition: none !important;
    transform: none !important;
  }
  /* Exceção deliberada: spinner sem movimento nenhum lê como "travou".
     Fade lento no lugar da rotação — não dispara resposta vestibular. */
  [data-motion-profile] .fa-spinner,
  [data-motion-profile] .fa-circle-notch {
    animation: safie-breathe 2s ease-in-out infinite !important;
  }
}
