/*
 * Ukari — vocabulário de movimento.
 *
 * O `ukari.css` descreve COMPONENTES (a moldura de tela, o quadro, a faixa de
 * confiança). Este arquivo descreve o que eles FAZEM: entrar, revelar,
 * acompanhar a rolagem, seguir o ponteiro, desfilar.
 *
 * TRÊS REGRAS QUE VALEM PARA TUDO AQUI
 *
 * 1. Só `opacity`, `transform` e `filter`. São as três propriedades que o
 *    compositor resolve sem recalcular layout. Animar `height`, `top` ou
 *    `margin` é o que transforma uma página bonita numa rolagem que treme no
 *    celular — e o celular é onde o dono de loja abre este site.
 *
 * 2. Nada nasce invisível sem JavaScript. Toda regra de entrada mora atrás de
 *    `.st-anima`, que o `movimento.js` acrescenta na raiz depois de rodar. Se o
 *    script falhar, a página fica parada e INTEIRA em vez de vazia — que é o
 *    modo de falhar correto para uma página que precisa vender.
 *
 * 3. `prefers-reduced-motion` desliga tudo, no fim do arquivo. Não é preferência
 *    estética: para parte das pessoas movimento em tela causa enjoo de verdade,
 *    e a lei de acessibilidade trata isso como requisito.
 *
 * COR: nada aqui declara cor literal fora de `rgba()` de sombreamento neutro.
 * O resto vem de `tokens.css`, senão o tema escuro quebra — e já quebrou.
 */

/* ==========================================================================
   1. ENTRADA AO ROLAR
   O `data-anima` sem valor continua valendo (dezenas de lugares o usam assim)
   e significa "sobe". Os valores nomeados são variações do mesmo gesto.
   ========================================================================== */

.st-anima .st-entra {
  opacity: 0;
  transition: opacity .6s cubic-bezier(.22, .61, .36, 1),
              transform .6s cubic-bezier(.22, .61, .36, 1),
              filter .6s cubic-bezier(.22, .61, .36, 1),
              clip-path .7s cubic-bezier(.22, .61, .36, 1);
  /* Avisa o compositor antes do primeiro quadro: sem isto a primeira entrada de
     cada seção engasga no celular. Removido ao terminar, porque `will-change`
     permanente reserva memória de vídeo por elemento e a página tem dezenas. */
  will-change: opacity, transform;
}

.st-anima [data-anima=""].st-entra,
.st-anima [data-anima="sobe"].st-entra { transform: translate3d(0, 22px, 0); }
.st-anima [data-anima="desce"].st-entra { transform: translate3d(0, -22px, 0); }
.st-anima [data-anima="esquerda"].st-entra { transform: translate3d(-28px, 0, 0); }
.st-anima [data-anima="direita"].st-entra { transform: translate3d(28px, 0, 0); }
.st-anima [data-anima="cresce"].st-entra { transform: scale(.93); }
.st-anima [data-anima="foco"].st-entra { filter: blur(10px); transform: translate3d(0, 12px, 0); }
/* A cortina: o bloco é revelado de baixo para cima, como uma persiana subindo.
   Guardado para painel de produto — é o gesto mais caro da página e perde a
   força se aparecer seis vezes. */
.st-anima [data-anima="cortina"].st-entra { clip-path: inset(100% 0 0 0); transform: none; opacity: 1; }

.st-anima .st-entra.st-visivel {
  opacity: 1;
  transform: none;
  filter: none;
  clip-path: inset(0 0 0 0);
  will-change: auto;
}

/* ==========================================================================
   2. MANCHETE PALAVRA POR PALAVRA
   O `movimento.js` embrulha cada palavra em duas camadas: a de fora corta, a de
   dentro sobe. É o gesto que faz um título parecer escrito na hora em vez de
   simplesmente aparecer.

   `overflow: hidden` numa linha de texto corta acento e perna de "g". O
   `padding-bottom` com `margin-bottom` negativo devolve o espaço sem mexer no
   ritmo vertical do título.
   ========================================================================== */

.st-palavra {
  display: inline-block;
  overflow: hidden;
  padding-bottom: .12em;
  margin-bottom: -.12em;
  vertical-align: top;
}

.st-palavra > span {
  display: inline-block;
  transform: translate3d(0, 105%, 0);
  transition: transform .78s cubic-bezier(.16, 1, .3, 1);
  will-change: transform;
}

.st-anima .st-letras.st-visivel .st-palavra > span { transform: none; }
/* Sem o script — ou depois que a animação terminou — o título é texto comum. */
.st-letras:not(.st-visivel):not(.st-pronto) { }
.st-pronto .st-palavra > span { will-change: auto; }

/* ==========================================================================
   3. BARRA DE PROGRESSO DA ROLAGEM
   Uma linha de 2px no topo. Existe por um motivo prático, não decorativo: estas
   páginas ficaram longas, e a barra é o que diz "falta pouco" para quem está
   decidindo se continua rolando.
   ========================================================================== */

.st-progresso {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 1040;
  height: 2px;
  background: var(--st-brand);
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
  /* Sem transição: o valor vem da rolagem a cada quadro, e interpolar por cima
     de um valor que já é contínuo produz atraso visível. */
}

/* ==========================================================================
   4. CENA PRESA (SCROLL SCRUB)
   `[data-cena]` é uma seção alta; dentro dela `[data-cena-palco]` gruda na tela
   e o JavaScript escreve `--p` (0 a 1) conforme a seção atravessa a janela.
   Tudo o que se move aqui lê `--p` — nada consulta a rolagem por conta própria.
   ========================================================================== */

/* TUDO NESTA SEÇÃO MORA ATRÁS DE `.st-anima`, e isso é o ponto.
   Um quadro de cena é `position: absolute` com `opacity: 0` — os quatro
   empilhados no mesmo lugar, esperando o JavaScript dizer qual está no ar. Sem
   essa proteção, um `movimento.js` que não carregue (rede ruim, extensão que
   bloqueia, erro de sintaxe num navegador antigo) deixaria a seção mais
   importante da home EM BRANCO, e sem sintoma nenhum.
   Com ela, a mesma marcação vira quatro blocos empilhados, visíveis e na ordem
   — feio, e legível. É o modo de falhar correto para uma página que vende. */

.st-cena { position: relative; }

.st-anima .st-cena-palco {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  /* `svh` respeita a barra do navegador móvel que aparece e some; com `vh` a
     cena pula 60px toda vez que a barra recolhe. */
  min-height: 100svh;
  overflow: hidden;
}

/* A ALTURA DE PERCURSO da cena também é da página, e também mora atrás de
   `.st-anima` — ver `.home-cena` no `home.html`. Sem o script, quatro telas de
   rolagem vazias apareceriam abaixo dos blocos empilhados. */

.st-anima .st-cena-quadro {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  opacity: 0;
  transform: translate3d(0, 30px, 0);
  transition: opacity .45s ease, transform .45s cubic-bezier(.22, .61, .36, 1);
  pointer-events: none;
}
.st-anima .st-cena-quadro.st-no-ar { opacity: 1; transform: none; pointer-events: auto; }

/* Empilhados, com respiro entre eles, quando o script não roda. */
.st-cena-quadro + .st-cena-quadro { margin-top: 3rem; }

/* Os passos numerados da cena, à esquerda. O ativo ganha tinta cheia; os outros
   ficam legíveis mas apagados — a diferença tem que se ler sem cor. */
.st-passos { list-style: none; margin: 0; padding: 0; display: grid; gap: .9rem; }
.st-passo {
  display: flex;
  gap: .8rem;
  align-items: baseline;
  color: var(--st-ink-faint);
  transition: color .3s ease, transform .3s cubic-bezier(.22, .61, .36, 1);
}
.st-passo b { font: 600 .72rem var(--st-font-mono); letter-spacing: .1em; }
.st-passo span { font-size: 1.02rem; font-weight: 550; letter-spacing: -.01em; }
.st-passo.st-ativo { color: var(--st-ink); transform: translateX(.4rem); }
.st-dark .st-passo { color: rgba(255, 255, 255, .42); }
.st-dark .st-passo.st-ativo { color: #ffffff; }

/* ==========================================================================
   5. DESFILE (MARQUEE)
   Duas cópias da mesma fita correndo lado a lado: quando a primeira sai, a
   segunda já está no lugar dela e o laço fecha sem salto. O conteúdo é
   duplicado pelo JavaScript, e `aria-hidden` na cópia impede o leitor de tela
   de ler tudo duas vezes.
   ========================================================================== */

.st-desfile {
  display: flex;
  overflow: hidden;
  gap: 0;
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.st-desfile-fita {
  display: flex;
  flex: none;
  align-items: center;
  gap: 2.5rem;
  padding-right: 2.5rem;
  white-space: nowrap;
  animation: st-desfilar var(--st-desfile-tempo, 38s) linear infinite;
}
.st-desfile:hover .st-desfile-fita { animation-play-state: paused; }
.st-desfile-item {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  font: 600 .82rem var(--st-font-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--st-ink-muted);
}
.st-desfile-item::after {
  content: "";
  width: .35rem;
  height: .35rem;
  border-radius: 50%;
  background: currentColor;
  opacity: .5;
}
.st-dark .st-desfile-item { color: rgba(255, 255, 255, .55); }

@keyframes st-desfilar {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-100%, 0, 0); }
}

/* ==========================================================================
   6. HOLOFOTE
   Um clarão suave que segue o ponteiro sobre superfícies escuras. `--mx`/`--my`
   vêm do JavaScript em porcentagem. Só em ponteiro fino: no telefone não há
   cursor, e o efeito ficaria preso no último toque.
   ========================================================================== */

.st-holofote::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity .4s ease;
  background: radial-gradient(
    32rem 32rem at var(--mx, 50%) var(--my, 40%),
    rgba(169, 156, 240, .18),
    transparent 65%);
}
@media (hover: hover) and (pointer: fine) {
  .st-anima .st-holofote:hover::after { opacity: 1; }
}

/* ==========================================================================
   7. ÍMÃ
   O botão principal se desloca alguns pixels na direção do ponteiro. O
   deslocamento é pequeno de propósito: o suficiente para o botão parecer vivo,
   pouco o bastante para o clique nunca errar o alvo.
   ========================================================================== */

.st-ima { transition: transform .25s cubic-bezier(.22, .61, .36, 1); }

/* Brilho que atravessa o botão. Um único gesto, na entrada do ponteiro. */
.st-brilho { position: relative; overflow: hidden; }
.st-brilho::before {
  content: "";
  position: absolute;
  top: 0;
  left: -140%;
  width: 60%;
  height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .38), transparent);
  transform: skewX(-18deg);
  pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
  .st-anima .st-brilho:hover::before { animation: st-passar .75s ease; }
}
@keyframes st-passar { to { left: 160%; } }

/* ==========================================================================
   8. CARTÃO QUE RESPONDE
   Deslocamento e linha, não sombra difusa: a linguagem do site é borda.
   ========================================================================== */

.st-anima .st-reage {
  transition: transform .28s cubic-bezier(.22, .61, .36, 1),
              border-color .28s ease, background-color .22s ease;
}
@media (hover: hover) and (pointer: fine) {
  .st-anima .st-reage:hover { transform: translateY(-4px); border-color: var(--st-line-strong); }
}

/* ==========================================================================
   9. DEMONSTRAÇÕES AO VIVO
   Estas não são enfeite: cada uma É o produto acontecendo. Uma imagem parada do
   mesmo painel precisaria de uma legenda explicando o que aconteceria — e
   legenda que explica figura é o sintoma de que a figura não conta a história.
   ========================================================================== */

/* 9a. O texto que vira bytes (Vault). O JavaScript troca o conteúdo; aqui fica
   só o piscar do cursor e a moldura. */
.st-cifra {
  min-height: 8.5rem;
  padding: 1rem;
  font: .82rem/1.65 var(--st-font-mono);
  word-break: break-all;
  color: var(--st-ink);
}
.st-cifra.st-cifrado { color: var(--st-ink-muted); }
.st-cifra .st-cursor {
  display: inline-block;
  width: .5ch;
  height: 1.05em;
  margin-left: .1ch;
  background: currentColor;
  vertical-align: text-bottom;
  animation: st-piscar 1.05s steps(2) infinite;
}
@keyframes st-piscar { 50% { opacity: 0; } }

/* 9b. O relógio do link que expira. */
.st-relogio {
  font: 700 clamp(2.2rem, 6vw, 3.6rem)/1 var(--st-font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}
.st-relogio.st-acabando { color: var(--st-danger); }

/* 9c. As aberturas chegando no registro de acesso. */
.st-registro { display: grid; gap: 1px; background: var(--st-line); }
.st-registro-linha {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: .75rem;
  align-items: center;
  padding: .6rem .9rem;
  background: var(--st-surface);
  font: .82rem var(--st-font-mono);
  animation: st-aparecer .5s cubic-bezier(.22, .61, .36, 1) both;
}
.st-dark .st-registro { background: #26262b; }
.st-dark .st-registro-linha { background: #151517; }
@keyframes st-aparecer {
  from { opacity: 0; transform: translate3d(0, -8px, 0); }
  to   { opacity: 1; transform: none; }
}

/* 9d. A linha de estoque que entra sozinha, como entra no sistema quando alguém
   dá baixa numa venda. */
.st-linha-nova { animation: st-chega 6s ease-in-out infinite; }
@keyframes st-chega {
  0%, 8%    { opacity: 0; transform: translateY(-6px); }
  16%, 88%  { opacity: 1; transform: none; }
  100%      { opacity: 0; transform: translateY(-6px); }
}

/* 9e. O cartão que atravessa as colunas do quadro. Um passo é a largura do
   cartão mais o respiro da coluna e o vão entre elas. Medido assim, e não em
   pixel, o cartão continua parando DENTRO da coluna quando o quadro muda de
   tamanho. */
.st-demo-card { animation: st-anda 9s cubic-bezier(.65, 0, .35, 1) infinite; }
@keyframes st-anda {
  0%, 20%   { transform: translate(0, 0); opacity: 1; }
  28%, 48%  { transform: translate(calc(100% + 2.25rem), 0); }
  56%, 76%  { transform: translate(calc(200% + 4.5rem), 0); }
  84%, 94%  { transform: translate(calc(300% + 6.75rem), 0); opacity: 1; }
  97%       { transform: translate(calc(300% + 6.75rem), 0); opacity: 0; }
  98%       { transform: translate(0, 0); opacity: 0; }
  100%      { transform: translate(0, 0); opacity: 1; }
}

/* 9f. O satélite dando a volta. É o símbolo da marca virando movimento sem
   tocar no símbolo: um ponto percorrendo uma órbita elíptica desenhada com a
   mesma inclinação de 20° dos anéis. */
.st-orbita { position: relative; display: inline-block; }
.st-orbita-satelite {
  position: absolute;
  top: 50%;
  left: 50%;
  width: .5rem;
  height: .5rem;
  margin: -.25rem 0 0 -.25rem;
  border-radius: 50%;
  background: currentColor;
  offset-path: path("M -120 0 A 120 34 0 1 1 120 0 A 120 34 0 1 1 -120 0");
  offset-rotate: 0deg;
  animation: st-orbitar 11s linear infinite;
}
@keyframes st-orbitar { to { offset-distance: 100%; } }
/* Sem `offset-path` (Safari antigo) o ponto ficaria empilhado no centro do
   símbolo, parecendo um defeito. Melhor não existir. */
@supports not (offset-path: path("M 0 0")) { .st-orbita-satelite { display: none; } }

/* ==========================================================================
   10. NÚMEROS
   ========================================================================== */

.st-numero {
  font-family: var(--st-font-display);
  font-variant-numeric: tabular-nums;
  font-size: clamp(2.4rem, 6vw, 4.2rem);
  font-weight: 700;
  letter-spacing: -.05em;
  line-height: 1;
}

/* ==========================================================================
   11. DESLIGAR
   Duas situações em que a página tem que ficar parada e inteira.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .st-anima .st-entra,
  .st-anima .st-entra.st-visivel { opacity: 1 !important; transform: none !important; filter: none !important; clip-path: none !important; }
  .st-palavra > span { transform: none !important; }
  .st-desfile-fita,
  .st-demo-card,
  .st-linha-nova,
  .st-registro-linha,
  .st-orbita-satelite { animation: none !important; }
  .st-cena-palco { position: static; min-height: 0; }
  .st-cena-quadro { position: static; opacity: 1; transform: none; pointer-events: auto; }
  .st-progresso { display: none; }
}

/* Impressão e PDF: uma página impressa é a captura de um instante — se metade
   dela ainda não "entrou", sai em branco. */
@media print {
  .st-anima .st-entra { opacity: 1 !important; transform: none !important; clip-path: none !important; filter: none !important; }
  .st-palavra > span { transform: none !important; }
  .st-desfile-fita, .st-demo-card, .st-linha-nova, .st-orbita-satelite { animation: none !important; }
  .st-progresso, .st-holofote::after { display: none !important; }
  .st-cena-palco { position: static; min-height: 0; }
  .st-cena-quadro { position: static; opacity: 1; transform: none; }
}

/* O ESTADO PARADO DO PAINEL DE CIFRA.
   O elemento traz, no HTML, o texto em claro e o bloco cifrado, um sobre o
   outro. Sem o `movimento.js` — movimento reduzido, script bloqueado, erro — é
   isso que a pessoa lê, e a mensagem chega inteira sem animação nenhuma. Com o
   script, ele troca o conteúdo pela versão que digita e cifra, e estas regras
   deixam de ter o que pintar. */
.st-cifra { display: grid; gap: .5rem; }
.st-cifra-claro { color: var(--uk-tinta, var(--st-ink)); }
.st-cifra-seta { color: var(--uk-tinta-3, var(--st-ink-faint)); }
.st-cifra-bytes { color: var(--uk-tinta-3, var(--st-ink-faint)); word-break: break-all; }
/* Com o script no ar o conteúdo é substituído, então o `grid` volta a ser fluxo
   normal de texto: uma linha só, com o cursor piscando no fim. */
.st-anima .st-cifra { display: block; }
