/*
 * motion.css — o movimento padrão de todos os produtos da Pixel Tech (DEC-051).
 *
 * Nada muda "de soco": página, clique, gaveta, janela e aviso entram e saem
 * com uma animação curta, sem pesar. Regras:
 *   - só transform e opacity (a placa de vídeo faz, o layout não recalcula);
 *   - de 150 a 250 ms, ease-out; troca de página em até 200 ms;
 *   - nada atrasa a ação: o clique responde na hora, a animação vem junto;
 *   - dado chegando não anima (Pix, QR, valores, telas ao vivo);
 *   - a entrada é só para quem chega na tela; uma escolha na mesma tela
 *     (filtro, dia, veículo, salvar e voltar) não anima a página (motion.js);
 *   - prefers-reduced-motion zera tudo; na impressão, nada;
 *   - sem biblioteca.
 *
 * COMO USAR
 * Copie este arquivo e o motion.js para a pasta pública do app e carregue os
 * dois no <head>, ANTES do CSS do app (que pode ajustar o que precisar); o
 * script sem defer nem async:
 *
 *   <link rel="stylesheet" href="/motion.css">
 *   <script src="/motion.js"></script>
 *
 * O motion.js põe .ptm-same no <html> quando a página fica na mesma tela; aí
 * não há fade da página nem entrada de lista ou bloco, e só o que tem
 * view-transition-name próprio se mexe. A tela é o caminho; quando abas ou
 * fichas têm caminho próprio mas são a mesma tela (abas do Estoque, a ficha
 * /customers/<id> com a lista ao lado), a página declara a chave:
 *
 *   <html data-ptm-screen="estoque">   ou   <meta name="ptm-screen" content="estoque">
 *
 * (o meta ANTES do motion.js). E a gaveta que já estava aberta na página
 * anterior da mesma tela aparece parada (.ptm-drawer-stay no <html>, que o
 * script põe e tira sozinho), sem deslizar de novo. Cada app tem conteúdo
 * diferente: este é a base, e o app escolhe onde pôr cada classe.
 *
 *   Troca de página   já vale sozinha (@view-transition). Marque o que não
 *                     deve se mexer: menu lateral .ptm-nav, barra do topo
 *                     .ptm-top, menu de baixo do celular .ptm-tabbar.
 *   Clique            .ptm-press em botão, linha clicável, cartão.
 *   Aviso             .ptm-toast no aviso de sucesso/erro (entra em 200 ms).
 *   Gaveta            .ptm-drawer (da direita no computador, de baixo no
 *                     celular). Abre e fecha pelo atributo hidden, por
 *                     <dialog open> ou por popover: a saída também é suave.
 *   Folha de baixo    .ptm-sheet (sempre de baixo).
 *   Janela por cima   .ptm-modal (fade + escala .96 → 1); o fundo escuro é
 *                     ::backdrop (dialog) ou .ptm-veil (div própria).
 *   Lista             .ptm-list-in no contêiner, só na PRIMEIRA carga: os 12
 *                     primeiros filhos entram em fade curto, os outros já
 *                     aparecem prontos. Tire a classe depois que a animação
 *                     acabar, para a lista não piscar a cada atualização:
 *                       setTimeout(() => el.classList.remove('ptm-list-in'), 600);
 *   Esperando         .ptm-busy no botão enquanto a ação roda (fica apagado
 *                     e mostra a rodinha, sem mudar de tamanho).
 *   Aparecer          .ptm-fade-in num bloco que surge na tela (ex.: o
 *                     resultado de uma busca).
 *
 * O QUE DESLIGAR
 * Ponha .ptm-still no contêiner (ou no <html>, para a página toda) de:
 *   - telas ao vivo que se atualizam sozinhas (pátio, cozinha, fila, TV);
 *   - arrastar e soltar (agenda, colunas): o item tem de seguir o dedo;
 *   - caixa/PDV: a venda não espera animação;
 *   - mapa, gráfico e canvas.
 * E nunca ponha classe de animação em valor, QR, código Pix ou número que
 * acabou de chegar do servidor.
 */

:root {
  --ptm-fast: 150ms;
  --ptm-base: 200ms;
  --ptm-slow: 250ms;
  --ptm-ease: cubic-bezier(.2, .8, .2, 1);
  --ptm-shift: 8px;
}

/* ── Troca de página ─────────────────────────────────────────────────────── */

@view-transition { navigation: auto; }

::view-transition-old(root) { animation: ptm-page-out var(--ptm-fast) var(--ptm-ease) both; }
::view-transition-new(root) { animation: ptm-page-in var(--ptm-base) var(--ptm-ease) both; }

.ptm-nav { view-transition-name: ptm-nav; }
.ptm-top { view-transition-name: ptm-top; }
.ptm-tabbar { view-transition-name: ptm-tabbar; }

/* Menu e topo ficam parados: troca direta, sem cruzar as duas imagens. */
::view-transition-group(ptm-nav),
::view-transition-group(ptm-top),
::view-transition-group(ptm-tabbar) { animation: none; }
::view-transition-old(ptm-nav),
::view-transition-old(ptm-top),
::view-transition-old(ptm-tabbar) { display: none; }
::view-transition-new(ptm-nav),
::view-transition-new(ptm-top),
::view-transition-new(ptm-tabbar) { animation: none; }

/* Página ao vivo, ou a mesma tela de volta (motion.js): troca sem animação.
   Só o que tem view-transition-name próprio se mexe. */
:root.ptm-still::view-transition-old(root),
:root.ptm-still::view-transition-new(root),
:root.ptm-same::view-transition-old(root),
:root.ptm-same::view-transition-new(root) { animation: none; }

@keyframes ptm-page-out { to { opacity: 0; } }
@keyframes ptm-page-in { from { opacity: 0; transform: translateY(6px); } }

/* ── Clique ──────────────────────────────────────────────────────────────── */

.ptm-press {
  transition: transform var(--ptm-fast) var(--ptm-ease);
}
.ptm-press:active:not(:disabled):not([aria-disabled="true"]) {
  transform: scale(.97);
  transition-duration: 60ms;
}

/* ── Aviso ───────────────────────────────────────────────────────────────── */

.ptm-toast { animation: ptm-rise var(--ptm-base) var(--ptm-ease) both; }

@keyframes ptm-rise { from { opacity: 0; transform: translateY(var(--ptm-shift)); } }

/* ── Gaveta, folha de baixo e janela por cima ────────────────────────────── */
/* A entrada usa @starting-style; a saída, transition-behavior: allow-discrete,
   que segura o display (hidden, dialog e popover) até a animação acabar. */

.ptm-drawer,
.ptm-sheet,
.ptm-modal,
.ptm-veil {
  transition:
    opacity var(--ptm-base) var(--ptm-ease),
    transform var(--ptm-slow) var(--ptm-ease),
    display var(--ptm-slow) allow-discrete,
    overlay var(--ptm-slow) allow-discrete;
}

/* Gaveta: da direita no computador. */
.ptm-drawer[hidden],
dialog.ptm-drawer:not([open]),
.ptm-drawer[popover]:not(:popover-open) { opacity: 0; transform: translateX(24px); }
@starting-style {
  .ptm-drawer:not([hidden]) { opacity: 0; transform: translateX(24px); }
}

/* Folha de baixo (e a gaveta no celular). */
.ptm-sheet[hidden],
dialog.ptm-sheet:not([open]),
.ptm-sheet[popover]:not(:popover-open) { opacity: 0; transform: translateY(32px); }
@starting-style {
  .ptm-sheet:not([hidden]) { opacity: 0; transform: translateY(32px); }
}
@media (max-width: 720px) {
  .ptm-drawer[hidden],
  dialog.ptm-drawer:not([open]),
  .ptm-drawer[popover]:not(:popover-open) { transform: translateY(32px); }
  @starting-style {
    .ptm-drawer:not([hidden]) { opacity: 0; transform: translateY(32px); }
  }
}

/* Janela por cima. */
.ptm-modal[hidden],
dialog.ptm-modal:not([open]),
.ptm-modal[popover]:not(:popover-open) { opacity: 0; transform: scale(.96); }
@starting-style {
  .ptm-modal:not([hidden]) { opacity: 0; transform: scale(.96); }
}

/* Fundo escuro. */
.ptm-veil[hidden] { opacity: 0; }
@starting-style { .ptm-veil:not([hidden]) { opacity: 0; } }

dialog.ptm-drawer::backdrop,
dialog.ptm-sheet::backdrop,
dialog.ptm-modal::backdrop {
  transition:
    opacity var(--ptm-base) var(--ptm-ease),
    display var(--ptm-base) allow-discrete,
    overlay var(--ptm-base) allow-discrete;
}
dialog.ptm-drawer:not([open])::backdrop,
dialog.ptm-sheet:not([open])::backdrop,
dialog.ptm-modal:not([open])::backdrop { opacity: 0; }
@starting-style {
  dialog.ptm-drawer[open]::backdrop,
  dialog.ptm-sheet[open]::backdrop,
  dialog.ptm-modal[open]::backdrop { opacity: 0; }
}

/* ── Lista: só a primeira carga, só os 12 primeiros ──────────────────────── */

.ptm-list-in > :nth-child(-n + 12) { animation: ptm-rise var(--ptm-base) var(--ptm-ease) both; }
.ptm-list-in > :nth-child(2) { animation-delay: 20ms; }
.ptm-list-in > :nth-child(3) { animation-delay: 40ms; }
.ptm-list-in > :nth-child(4) { animation-delay: 60ms; }
.ptm-list-in > :nth-child(5) { animation-delay: 80ms; }
.ptm-list-in > :nth-child(6) { animation-delay: 100ms; }
.ptm-list-in > :nth-child(n + 7):nth-child(-n + 12) { animation-delay: 120ms; }

/* Escolha na mesma tela: a lista e os blocos já estão lá, não entram de novo. */
:root.ptm-same .ptm-list-in > *,
:root.ptm-same .ptm-fade-in { animation: none; }

/* A gaveta que já estava aberta antes aparece parada (motion.js tira a classe
   depois do carregamento, e fechar volta a ser suave). */
:root.ptm-drawer-stay .ptm-drawer,
:root.ptm-drawer-stay dialog.ptm-drawer::backdrop { transition: none; }

/* ── Aparecer e esperar ──────────────────────────────────────────────────── */

.ptm-fade-in { animation: ptm-fade var(--ptm-base) var(--ptm-ease) both; }
@keyframes ptm-fade { from { opacity: 0; } }

.ptm-busy {
  position: relative;
  pointer-events: none;
  color: transparent !important;
}
.ptm-busy::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-color: var(--ptm-busy-color, #fff) transparent var(--ptm-busy-color, #fff) var(--ptm-busy-color, #fff);
  border-radius: 50%;
  animation: ptm-spin .7s linear infinite;
}
@keyframes ptm-spin { to { transform: rotate(360deg); } }

/* ── Desligar ────────────────────────────────────────────────────────────── */

.ptm-still,
.ptm-still * {
  animation: none !important;
}
.ptm-still .ptm-press:active { transform: none; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  *, *::before, *::after,
  ::backdrop {
    animation-duration: .01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
  }
  .ptm-busy::after { animation: none; border-color: var(--ptm-busy-color, #fff); opacity: .6; }
}

@media print {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}
