/* Sinais vivos (W19): microinterações decorativas. Só atinge classes vs-* e
   nós vs-* injetados por vivo-sinais.js (aria-hidden, absolutos, sem ponteiro).
   Sem JS nada muda. Modos (classes postas por vivo.js no <html>): completo;
   vivo-leve (igual, sem decodificação); vivo-calmo (0,45× de velocidade,
   nada pisca, nada gira nem cresce, nada segue o ponteiro, nenhum laço de
   4 a 6 s); vivo-quieto ou vivo-parado (quadro final fixo, nenhuma animação
   nem transição). Cores forçadas: camada oculta em qualquer modo.
   Leitura: nenhum brilho passa atrás de texto com alfa acima de 0,12; os
   efeitos contínuos animam só transform ou opacity (compositor); filter só em
   brilho fixo, nunca animado em laço. Resposta a hover ou foco: transição de
   até 300 ms; movimento no hover só com ponteiro fino. */

@property --vs-angulo {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.vs-rel { position: relative; }

vs-decod, vs-claro, vs-ruido, vs-cursor, vs-brilho, vs-filete, vs-topo-linha, vs-progresso,
vs-progresso-cheio, vs-progresso-ponta, vs-medidor, vs-barra, vs-barra-vazia, vs-reflexo, vs-etapa, vs-trilho, vs-holofote {
  pointer-events: none !important;
  user-select: none;
}
/* Nó absoluto dentro de uma grade: a colocação herdada de regras "> *" da
   página (grid-column) não pode encolher o bloco de contenção dele. */
vs-brilho, vs-filete, vs-trilho { grid-area: auto !important; }

/* 1. Decodificação: camada criada na carga, invisível e contida (o relayout
   da troca do ruído fica dentro dela), do tamanho do texto e recortada só na
   horizontal (nada escapa para a rolagem da página). Aparece só durante a
   animação, quando o original fica transparente (só no modo completo). O
   avanço é um recorte escrito pelo tique do JS (~15 Hz). */
vs-decod {
  position: absolute !important;
  top: 0;
  left: 0;
  z-index: 1 !important;
  display: block !important;
  box-sizing: content-box !important;
  width: var(--vs-w, 0px) !important;
  min-width: 0 !important;
  max-width: none !important;
  height: 0 !important;
  min-height: 0 !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  overflow-x: clip !important;
  overflow-y: visible !important;
  overflow-clip-margin: 10px;
  visibility: hidden !important;
  contain: size layout style;
  text-align: left;
  text-indent: 0;
  white-space: pre;
  -webkit-text-fill-color: currentcolor;
}
@media (prefers-reduced-motion: no-preference) {
  html:not(.vivo-parado):not(.vivo-quieto):not(.vivo-calmo):not(.vivo-leve) .vs-decod-ativo {
    -webkit-text-fill-color: transparent;
    text-shadow: none !important;
  }
  html:not(.vivo-parado):not(.vivo-quieto):not(.vivo-calmo):not(.vivo-leve) .vs-decod-ativo > vs-decod { visibility: visible !important; }
}
/* Cópia do texto (trecho já decodificado) e ruído (o resto), na mesma origem
   e com a mesma largura; o recorte (clip-path) separa os dois. */
vs-claro,
vs-ruido {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  box-sizing: content-box;
  width: var(--vs-w, 0px);
  min-width: 0;
  max-width: none;
  margin: 0;
  padding: 0;
  border: 0;
  text-align: left;
  text-indent: 0;
  white-space: pre;
  -webkit-text-fill-color: currentcolor;
}
vs-ruido { overflow-x: clip; overflow-y: visible; }
.vs-decod--escuro vs-ruido { color: #38E8FF; text-shadow: 0 0 9px rgba(56, 232, 255, .6); }
.vs-decod--claro vs-ruido { color: #0B5CE8; text-shadow: 0 0 7px rgba(56, 232, 255, .45); }

/* 2. Cursor de terminal depois do rótulo do topo: pisca quatro vezes (< 5 s)
   e fica aceso. -------------------------------------------------------------- */
vs-cursor {
  position: absolute !important;
  display: block;
  width: .55em;
  height: 1em;
  background: #0B5CE8;
  opacity: .95;
  -webkit-text-fill-color: currentcolor;
  animation: vs-piscar 1.06s linear .4s 4 both;
}
vs-cursor.vs-cursor--escuro {
  background: #38E8FF;
  box-shadow: 0 0 10px rgba(56, 232, 255, .65), 0 0 2px rgba(214, 251, 255, .9);
}
@keyframes vs-piscar {
  0%, 52% { opacity: .95; }
  56%, 96% { opacity: 0; }
  100% { opacity: .95; }
}

/* 4. Cartões vivos: anel de luz na borda e holofote que segue o ponteiro. No
   hover ou foco o anel acende (opacidade) e a luz desliza um trecho da borda
   (ângulo do gradiente, uma vez, em 300 ms; sem laço de repintura). -------- */
.vs-cartao { isolation: isolate; }
vs-brilho {
  position: absolute !important;
  inset: -1px !important;
  z-index: -1 !important;
  display: block;
  border-radius: inherit;
  opacity: 0;
  box-shadow: inset 0 0 36px rgba(56, 232, 255, .07);
  transition: opacity .25s ease-out;
}
.vs-cartao--recorte > vs-brilho { inset: 0 !important; }
.vs-cartao--aberto > vs-brilho { inset: -1px -.85rem -.9rem !important; border-radius: 12px; box-shadow: none; }
vs-brilho::before,
vs-brilho::after {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  content: "";
}
vs-brilho::before {
  padding: 1.5px;
  background: conic-gradient(from var(--vs-angulo), rgba(56, 232, 255, 0) 0deg, rgba(56, 232, 255, .15) 30deg, #38E8FF 80deg, #EAFDFF 96deg, #5B8CFF 118deg, rgba(91, 140, 255, 0) 170deg, rgba(56, 232, 255, 0) 190deg, rgba(56, 232, 255, .2) 220deg, #38E8FF 262deg, #0B5CE8 300deg, rgba(11, 92, 232, 0) 350deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  transition: --vs-angulo .3s ease-out;
}
vs-brilho::after {
  background: radial-gradient(26rem circle at var(--vs-mx, 50%) var(--vs-my, 0%), rgba(56, 232, 255, .12), rgba(11, 92, 232, .05) 42%, rgba(11, 92, 232, 0) 70%);
}
.vs-cartao--claro > vs-brilho { box-shadow: inset 0 0 32px rgba(11, 92, 232, .05); }
.vs-cartao--claro > vs-brilho::before {
  background: conic-gradient(from var(--vs-angulo), rgba(11, 92, 232, 0) 0deg, rgba(11, 92, 232, .2) 30deg, #0B5CE8 80deg, #38E8FF 100deg, #5B8CFF 122deg, rgba(91, 140, 255, 0) 170deg, rgba(11, 92, 232, 0) 190deg, rgba(11, 92, 232, .2) 220deg, #0B5CE8 262deg, #38E8FF 290deg, rgba(56, 232, 255, 0) 350deg);
}
.vs-cartao--claro > vs-brilho::after {
  background: radial-gradient(26rem circle at var(--vs-mx, 50%) var(--vs-my, 0%), rgba(11, 92, 232, .08), rgba(56, 232, 255, .04) 45%, rgba(56, 232, 255, 0) 72%);
}
.vs-cartao--aberto > vs-brilho::before { display: none; }
.vs-cartao:focus-within > vs-brilho { opacity: 1; }
.vs-cartao:focus-within > vs-brilho::before { --vs-angulo: 90deg; }
@media (hover: hover) and (pointer: fine) {
  .vs-cartao:hover > vs-brilho { opacity: 1; }
  .vs-cartao:hover > vs-brilho::before { --vs-angulo: 90deg; }
}
/* Sem recorte, o brilho também escapa um pouco para fora da borda. */
.vs-cartao--escuro:not(.vs-cartao--recorte):not(.vs-cartao--aberto) > vs-brilho {
  box-shadow: 0 0 28px rgba(56, 232, 255, .16), 0 0 2px rgba(56, 232, 255, .35), inset 0 0 36px rgba(56, 232, 255, .08);
}
.vs-cartao--claro:not(.vs-cartao--recorte):not(.vs-cartao--aberto) > vs-brilho {
  box-shadow: 0 0 26px rgba(11, 92, 232, .14), inset 0 0 32px rgba(11, 92, 232, .05);
}
/* Painéis grandes de moldura com cantoneiras (.vs-painel, vivo-sinais.js 4a; Tiago, 04/10 ~20h30:
   "não está acendendo nem ficando com efeito de luz"). No hover a moldura inteira acende: o anel
   corre como o dos cartões sobre uma borda acesa por inteiro (num painel largo, os trechos fortes do
   anel cônico cobrem pouco da borda), as cantoneiras de futuro.css acendem por cima (mesma geometria,
   ::after) e o halo de fora cresce. A luz que segue o ponteiro é um disco (vs-holofote) numa camada
   própria, que o script só desloca (transform; repintar um gradiente do tamanho do painel a cada
   quadro custava caro, M42); o brilho é um contêiner de tamanho e 50cqw/0cqh é o repouso. M35: o
   disco tem .12 no centro, como o ::after dos cartões, e o brilho de dentro da borda é curto. Acende
   só no hover: o painel não é interativo, e o foco de um link de dentro já tem o anel do link. */
.vs-painel > vs-brilho { overflow: hidden; container-type: size; }
.vs-cartao--escuro.vs-painel > vs-brilho::before {
  background:
    conic-gradient(from var(--vs-angulo), rgba(56, 232, 255, 0) 0deg, rgba(56, 232, 255, .15) 30deg, #38E8FF 80deg, #EAFDFF 96deg, #5B8CFF 118deg, rgba(91, 140, 255, 0) 170deg, rgba(56, 232, 255, 0) 190deg, rgba(56, 232, 255, .2) 220deg, #38E8FF 262deg, #0B5CE8 300deg, rgba(11, 92, 232, 0) 350deg),
    linear-gradient(rgba(56, 232, 255, .5), rgba(56, 232, 255, .5));
}
/* Cantoneiras acesas: as 8 barras de 2 px e o brilho de 6 px de futuro.css (F11/D5/D6), mais claros.
   O brilho fica a 1 px da borda (inset -1px); no painel com recorte, na própria caixa. */
.vs-painel > vs-brilho::after {
  --vs-c: 11px;
  --vs-cl: 9px;
  --vs-canto: linear-gradient(#EAFDFF, #EAFDFF);
  --vs-canto-luz: linear-gradient(rgba(56, 232, 255, .55), rgba(56, 232, 255, .55));
  background:
    var(--vs-canto), var(--vs-canto), var(--vs-canto), var(--vs-canto),
    var(--vs-canto), var(--vs-canto), var(--vs-canto), var(--vs-canto),
    var(--vs-canto-luz), var(--vs-canto-luz), var(--vs-canto-luz), var(--vs-canto-luz);
  background-position:
    var(--vs-c) var(--vs-c), var(--vs-c) var(--vs-c), calc(100% - var(--vs-c)) var(--vs-c), calc(100% - var(--vs-c)) var(--vs-c),
    var(--vs-c) calc(100% - var(--vs-c)), var(--vs-c) calc(100% - var(--vs-c)), calc(100% - var(--vs-c)) calc(100% - var(--vs-c)), calc(100% - var(--vs-c)) calc(100% - var(--vs-c)),
    var(--vs-cl) var(--vs-cl), var(--vs-cl) var(--vs-cl), calc(100% - var(--vs-cl)) calc(100% - var(--vs-cl)), calc(100% - var(--vs-cl)) calc(100% - var(--vs-cl));
  background-size:
    18px 2px, 2px 18px, 18px 2px, 2px 18px, 18px 2px, 2px 18px, 18px 2px, 2px 18px,
    22px 6px, 6px 22px, 22px 6px, 6px 22px;
  background-repeat: no-repeat;
}
.vs-painel.vs-cartao--recorte > vs-brilho::after { --vs-c: 10px; --vs-cl: 8px; }
/* /enterprise/: o subpainel de conteúdo do protótipo (.blueprint-metodo__painel, fundo opaco) vai até
   a borda direita e o pé e cobria ali o anel, as cantoneiras e a luz, que ficam atrás do conteúdo (a
   moldura acendia só em "L"). Neste painel o brilho vai por cima do conteúdo: o anel é só o aro da
   borda (máscara), as cantoneiras ficam nos 28 px dos cantos e a luz (.12 no centro) é um reflexo no
   vidro do console, sem tirar contraste do texto (pior caso 7,8:1). Nada clica no protótipo, e a
   camada não recebe ponteiro (pointer-events: none no topo deste arquivo). */
.vs-painel.blueprint-metodo > vs-brilho { z-index: 1 !important; }
vs-holofote {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 58rem;
  height: 58rem;
  margin: -29rem 0 0 -29rem;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(56, 232, 255, .12), rgba(56, 232, 255, .085) 40%, rgba(11, 92, 232, .035) 75%, rgba(11, 92, 232, 0) 100%);
  transform: translate(50cqw, 0cqh);
}
/* Camada própria só enquanto o ponteiro está no painel (fora dele, nenhuma camada a mais). */
.vs-painel:hover > vs-brilho > vs-holofote { will-change: transform; }
.vs-cartao--escuro.vs-painel:not(.vs-cartao--recorte) > vs-brilho {
  box-shadow: 0 0 48px rgba(56, 232, 255, .2), 0 0 2px rgba(56, 232, 255, .45), inset 0 0 40px rgba(56, 232, 255, .05);
}
@media (prefers-contrast: no-preference), (prefers-contrast: less), (prefers-contrast: custom) {
  .vs-painel:focus-within > vs-brilho { opacity: 0; }
  .vs-painel:focus-within > vs-brilho::before { --vs-angulo: 0deg; }
}
@media (hover: hover) and (pointer: fine) {
  .vs-painel:hover > vs-brilho { opacity: 1; }
  .vs-painel:hover > vs-brilho::before { --vs-angulo: 90deg; }
  /* Com recorte (overflow do próprio painel), o halo de fora vai na sombra do painel. */
  .site-clean.tema-escuro:not(.home-clean) main .vs-painel.vs-cartao--recorte:hover {
    box-shadow: var(--fx-reflexo), var(--fx-halo), 0 0 48px rgba(56, 232, 255, .2), 0 0 2px rgba(56, 232, 255, .45);
  }
}
/* Cartão aberto (só filete no topo): o filete inteiro acende no hover. */
.vs-cartao--aberto > vs-filete { transition: background-color .3s ease-out; }
.vs-cartao--aberto:focus-within > vs-filete { background-color: rgba(56, 232, 255, .7); }
@media (hover: hover) and (pointer: fine) {
  .vs-cartao--aberto:hover > vs-filete { background-color: rgba(56, 232, 255, .7); }
}

/* 5. Botões: reflexo que corre só pelo anel da borda (nunca atrás do texto),
   na cor do próprio texto do botão; setas com sublinhado fluindo. ------------ */
vs-reflexo {
  position: absolute !important;
  inset: -1px !important;
  display: block;
  overflow: hidden;
  box-sizing: border-box;
  padding: 1.5px;
  border-radius: inherit;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
}
vs-reflexo::before {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 42%;
  content: "";
  background: linear-gradient(100deg, rgba(56, 232, 255, 0) 0%, rgba(56, 232, 255, .55) 30%, #38E8FF 42%, currentcolor 50%, #38E8FF 58%, rgba(56, 232, 255, .55) 70%, rgba(56, 232, 255, 0) 100%);
  transform: translateX(-110%);
  transition: transform .3s ease-out;
  animation: vs-reflexo 6.4s ease-in-out var(--vs-atraso, 1.4s) infinite;
}
/* Hover ou foco: o reflexo atravessa a borda por transição (parte de onde o
   laço estava; sair no meio o devolve sem salto) e o laço recomeça depois. */
.vs-luz:focus-visible > vs-reflexo::before { animation: none; transform: translateX(250%); }
@media (hover: hover) and (pointer: fine) {
  .vs-luz:hover > vs-reflexo::before { animation: none; transform: translateX(250%); }
}
.vs-luz:disabled > vs-reflexo,
.vs-luz[aria-disabled="true"] > vs-reflexo { display: none; }
@keyframes vs-reflexo {
  0% { transform: translateX(-110%); }
  17%, 100% { transform: translateX(250%); }
}

/* Seta: anda por transform (o espaço do conteúdo " →" preservado); o
   sublinhado vira um gradiente fixo, sem laço. */
.vs-seta::after { display: inline-block; white-space: pre; transition: transform .25s ease-out; }
.vs-seta:focus-visible::after { transform: translateX(.22em); }
.vs-seta:focus-visible {
  text-decoration-color: transparent;
  background-image: linear-gradient(90deg, #0B5CE8 0%, #38E8FF 30%, #5B8CFF 55%, #38E8FF 80%, #0B5CE8 100%) !important;
  background-size: 10rem 2px !important;
  background-repeat: repeat-x !important;
  background-position: 0 100%;
}
@media (hover: hover) and (pointer: fine) {
  .vs-seta:hover::after { transform: translateX(.22em); }
  .vs-seta:hover {
    text-decoration-color: transparent;
    background-image: linear-gradient(90deg, #0B5CE8 0%, #38E8FF 30%, #5B8CFF 55%, #38E8FF 80%, #0B5CE8 100%) !important;
    background-size: 10rem 2px !important;
    background-repeat: repeat-x !important;
    background-position: 0 100%;
  }
}

/* 6. Cabeçalho: dois cometas na borda (transform) e progresso de leitura logo
   abaixo. Correm na carga e durante a rolagem; parados, apagam e pausam. ----- */
vs-topo-linha {
  position: absolute !important;
  right: 0;
  bottom: -1px;
  left: 0;
  z-index: 1;
  display: block;
  height: 1px;
  overflow-x: clip;
  overflow-y: visible;
  transition: opacity .8s ease;
}
vs-topo-linha::before,
vs-topo-linha::after {
  position: absolute;
  top: 0;
  left: 0;
  height: 1px;
  content: "";
  filter: drop-shadow(0 0 3px rgba(56, 232, 255, .9));
  animation: vs-cometa-ida 8.5s linear infinite;
}
vs-topo-linha::before {
  width: 15.4%;
  background: linear-gradient(90deg, rgba(56, 232, 255, 0) 0%, #38E8FF 86%, #EAFDFF 97%, rgba(56, 232, 255, 0) 100%);
}
vs-topo-linha::after {
  width: 9.6%;
  background: linear-gradient(90deg, rgba(91, 140, 255, 0) 0%, #EAFDFF 3%, #5B8CFF 15%, rgba(91, 140, 255, 0) 100%);
  animation-name: vs-cometa-volta;
}
@keyframes vs-cometa-ida {
  from { transform: translateX(-100%); }
  to { transform: translateX(650%); }
}
@keyframes vs-cometa-volta {
  from { transform: translateX(1042%); }
  to { transform: translateX(-100%); }
}
vs-topo-linha.vs-dorme { opacity: 0; }
vs-topo-linha.vs-dorme::before,
vs-topo-linha.vs-dorme::after { animation-play-state: paused; }

vs-progresso {
  position: absolute !important;
  top: calc(100% + 1px);
  right: 0;
  left: 0;
  z-index: -1;
  display: block;
  height: 2px;
  overflow-x: clip;
  overflow-y: visible;
}
vs-progresso-cheio {
  position: absolute;
  inset: 0;
  display: block;
  overflow: hidden;
  background: linear-gradient(90deg, #0B5CE8 0%, #5B8CFF 55%, #38E8FF 100%);
  box-shadow: 0 0 9px rgba(56, 232, 255, .45);
  transform: scaleX(0);
  transform-origin: 0 50%;
}
vs-progresso-cheio::after {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 16%;
  content: "";
  background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .95) 50%, rgba(255, 255, 255, 0) 100%);
  transition: opacity .6s ease;
  animation: vs-pacote 2.8s linear infinite;
}
@keyframes vs-pacote {
  from { transform: translateX(-100%); }
  to { transform: translateX(625%); }
}
vs-progresso.vs-zero vs-progresso-cheio::after,
vs-progresso.vs-dorme vs-progresso-cheio::after { opacity: 0; animation-play-state: paused; }
/* A ponta é uma faixa da largura da barra que anda por transform; o ponto fica
   na borda direita dela, sempre no fim do trecho preenchido. */
vs-progresso-ponta {
  position: absolute;
  inset: 0;
  display: block;
  transform: translateX(-100%);
  transition: opacity .3s ease;
}
vs-progresso-ponta::before {
  position: absolute;
  top: -2px;
  right: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #EAFDFF;
  box-shadow: 0 0 10px 2px rgba(56, 232, 255, .85);
  content: "";
}
vs-progresso.vs-zero vs-progresso-ponta { opacity: 0; }
/* Com linha do tempo de rolagem, a barra segue a rolagem no compositor. */
@supports (animation-timeline: scroll()) {
  vs-progresso.vs-progresso--css vs-progresso-cheio {
    animation: vs-progresso-encher linear both;
    animation-timeline: scroll(root block);
  }
  vs-progresso.vs-progresso--css vs-progresso-ponta {
    transition: none;
    animation: vs-progresso-ponta linear both;
    animation-timeline: scroll(root block);
  }
}
@keyframes vs-progresso-encher {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}
@keyframes vs-progresso-ponta {
  0% { opacity: 0; transform: translateX(-100%); }
  .4% { opacity: 1; }
  100% { opacity: 1; transform: translateX(0); }
}

/* 7. Home: trilha do método (pulso, números e nós), medidores, filetes. -------- */
/* Pulso: mora num trilho próprio (vs-trilho, na 1ª etapa) do tamanho exato do
   trecho entre o selo da primeira etapa e o centro do da última, no eixo do
   conector; o trilho recorta o pulso, que sai da borda do primeiro selo, passa
   sob os seguintes (pintados depois) e termina sob o último. O pulso é um pseudo
   do comprimento do trilho mais o rastro, deslocado só por transform. Cores por
   variáveis: ciano em fundo escuro, cobalto em fundo claro. */
.vs-trilha {
  --vs-p-nucleo: #FFFFFF;
  --vs-p-1: rgba(158, 245, 255, .95);
  --vs-p-2: rgba(56, 232, 255, .35);
  --vs-p-3: rgba(56, 232, 255, .55);
  --vs-p-4: #9FF5FF;
  --vs-p-brilho: rgba(56, 232, 255, .95);
  --vs-p-fixo: rgba(56, 232, 255, .55);
  --vs-p-fixo-2: rgba(56, 232, 255, .18);
}
.vs-trilha--clara {
  --vs-p-nucleo: #0B5CE8;
  --vs-p-1: rgba(11, 92, 232, .9);
  --vs-p-2: rgba(56, 232, 255, .4);
  --vs-p-3: rgba(11, 92, 232, .45);
  --vs-p-4: #0B5CE8;
  --vs-p-brilho: rgba(56, 232, 255, .75);
  --vs-p-fixo: rgba(11, 92, 232, .5);
  --vs-p-fixo-2: rgba(11, 92, 232, .15);
}
vs-trilho {
  position: absolute !important;
  display: block;
  width: 24px;
  height: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
vs-trilho.vs-h { width: 0; height: 24px; }
vs-trilho.vs-sem { display: none; }
vs-trilho::before {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: calc(100% + 120px);
  content: "";
  background-image:
    radial-gradient(circle at 50% 50%, var(--vs-p-nucleo) 0 1.6px, var(--vs-p-1) 2.4px, var(--vs-p-2) 3.6px, rgba(56, 232, 255, 0) 5px),
    linear-gradient(180deg, rgba(56, 232, 255, 0) 0%, var(--vs-p-3) 62%, var(--vs-p-4) 94%, rgba(56, 232, 255, 0) 100%);
  background-position: 50% 100%, 50% calc(100% - 5px);
  background-repeat: no-repeat;
  background-size: 10px 10px, 3px 120px;
  filter: drop-shadow(0 0 6px var(--vs-p-brilho));
  transform: translateY(-100%);
  animation: vs-trilho-v var(--vs-ciclo, 7.2s) linear infinite;
}
vs-trilho.vs-h::before {
  right: auto;
  bottom: 0;
  width: calc(100% + 120px);
  height: auto;
  background-image:
    radial-gradient(circle at 50% 50%, var(--vs-p-nucleo) 0 1.6px, var(--vs-p-1) 2.4px, var(--vs-p-2) 3.6px, rgba(56, 232, 255, 0) 5px),
    linear-gradient(90deg, rgba(56, 232, 255, 0) 0%, var(--vs-p-3) 62%, var(--vs-p-4) 94%, rgba(56, 232, 255, 0) 100%);
  background-position: 100% 50%, calc(100% - 5px) 50%;
  background-size: 10px 10px, 120px 3px;
  transform: translateX(-100%);
  animation-name: vs-trilho-h;
}
@keyframes vs-trilho-v {
  0% { transform: translateY(-100%); }
  70%, 100% { transform: translateY(0); }
}
@keyframes vs-trilho-h {
  0% { transform: translateX(-100%); }
  70%, 100% { transform: translateX(0); }
}
/* Nó de circuito: aceso por inteiro, esmaecido por opacidade em repouso. */
.vs-trilha--nos > li::after {
  position: absolute;
  top: calc(var(--vs-no-y, 10px) - 3.5px);
  left: calc(var(--vs-no-x, 0px) - 3.5px);
  width: 7px;
  height: 7px;
  box-sizing: border-box;
  border: 1px solid #EAFDFF;
  border-radius: 50%;
  background: radial-gradient(circle, #38E8FF 0 1.8px, #0B1422 2.3px);
  box-shadow: 0 0 12px rgba(56, 232, 255, .95);
  content: "";
  pointer-events: none;
  opacity: .3;
  animation: vs-no var(--vs-ciclo, 7.2s) linear var(--vs-atraso, 0s) infinite;
}
@keyframes vs-no {
  0% { opacity: .3; }
  4% { opacity: 1; }
  40%, 100% { opacity: .3; }
}
/* Selo da etapa: anel próprio sobre o selo numerado, com brilho fixo; acende
   quando o pulso passa e se abre como um sinal recebido. Anima só opacity e
   transform (compositor); o algarismo e o selo original não mudam. */
vs-etapa {
  position: absolute !important;
  top: 0;
  left: 0;
  display: block;
  box-sizing: border-box;
  width: 2.5rem;
  height: 2.5rem;
  margin: 0;
  border: 1px solid rgba(56, 232, 255, .9);
  border-radius: 999px;
  box-shadow: 0 0 12px rgba(56, 232, 255, .42), 0 0 2px rgba(56, 232, 255, .7), inset 0 0 9px rgba(56, 232, 255, .2);
  opacity: 0;
  animation: vs-etapa var(--vs-ciclo, 7.2s) linear var(--vs-atraso, 0s) infinite;
}
.vs-trilha--clara vs-etapa {
  border-color: rgba(11, 92, 232, .85);
  box-shadow: 0 0 12px rgba(11, 92, 232, .3), 0 0 2px rgba(56, 232, 255, .55), inset 0 0 8px rgba(56, 232, 255, .18);
}
@keyframes vs-etapa {
  0% { opacity: 0; transform: scale(1); }
  3% { opacity: 1; transform: scale(1); }
  24% { opacity: 0; transform: scale(1.22); }
  100% { opacity: 0; transform: scale(1.22); }
}

vs-medidor {
  position: absolute !important;
  z-index: 1;
  display: flex;
  gap: 4px;
  transform: translateY(-50%);
}
vs-barra,
vs-barra-vazia {
  position: relative;
  display: block;
  width: 18px;
  height: 5px;
  overflow: hidden;
  border-radius: 999px;
  background: #1C3150;
}
vs-barra {
  background: linear-gradient(90deg, #5B8CFF, #38E8FF);
  box-shadow: 0 0 10px rgba(56, 232, 255, .4);
}
vs-barra::after {
  position: absolute;
  inset: 0;
  content: "";
  background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .9) 50%, rgba(255, 255, 255, 0) 100%);
  transform: translateX(-110%);
  animation: vs-barra-fluxo 2.4s ease-in-out infinite;
}
vs-barra:nth-child(2)::after { animation-delay: .22s; }
vs-barra:nth-child(3)::after { animation-delay: .44s; }
@keyframes vs-barra-fluxo {
  0% { transform: translateX(-110%); }
  45%, 100% { transform: translateX(110%); }
}

/* Filete: cometa de 1 px correndo por transform, recortado na horizontal. */
vs-filete {
  --vs-curva-filete: cubic-bezier(.45, .05, .4, 1);
  position: absolute !important;
  top: -1px;
  right: 0;
  left: 0;
  z-index: 1;
  display: block;
  height: 1px;
  overflow-x: clip;
  overflow-y: visible;
}
vs-filete::before {
  position: absolute;
  top: 0;
  left: 0;
  width: 38%;
  height: 100%;
  content: "";
  background: linear-gradient(90deg, rgba(56, 232, 255, 0) 0%, rgba(56, 232, 255, .35) 55%, #38E8FF 88%, #EAFDFF 97%, rgba(56, 232, 255, 0) 100%);
  filter: drop-shadow(0 0 4px rgba(56, 232, 255, .95));
  transform: translateX(-115%);
  animation: vs-filete 5.7s var(--vs-curva-filete) var(--vs-atraso, 0s) infinite;
}
@keyframes vs-filete {
  0% { transform: translateX(-115%); }
  46%, 100% { transform: translateX(280%); }
}
/* W19q r3: o filete do cartão fica dentro da curva do canto. Com 3 px de altura o raio herdado
   quase não curva, e a faixa de ponta a ponta sobrava para fora da borda redonda nos dois cantos
   de cima (as "orelhas" do achado r2). Agora ela é recuada o raio do cartão (--vs-recuo, posto pelo
   vivo-sinais.js a partir do raio lido; 18 px de reserva), sem raio próprio, e esmaece nas pontas. */
vs-filete.vs-filete--cartao {
  top: 0;
  right: var(--vs-recuo, 18px);
  left: var(--vs-recuo, 18px);
  height: 3px;
  overflow: hidden;
  border-radius: 0;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
}
vs-filete.vs-filete--cartao::before {
  left: -200%;
  width: 400%;
  background: linear-gradient(90deg, #0B5CE8 0%, #38E8FF 25%, #5B8CFF 50%, #38E8FF 75%, #0B5CE8 100%) repeat-x;
  background-size: 50% 100%;
  filter: none;
  transform: translateX(0);
  animation: vs-cartao-sinal 6s linear infinite;
}
@keyframes vs-cartao-sinal {
  from { transform: translateX(0); }
  to { transform: translateX(50%); }
}
/* Linha do topo das colunas abertas (aplicações da Home): cometa de 2 px sobre
   a linha, saindo do traço de destaque; a caixa tem folga vertical para o
   brilho e esmaece no fim da coluna (a linha continua pelo vão). */
vs-filete.vs-filete--linha {
  top: -5px;
  height: 10px;
  overflow-x: clip;
  overflow-y: visible;
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 70%, transparent 100%);
  mask-image: linear-gradient(90deg, #000 0%, #000 70%, transparent 100%);
}
vs-filete.vs-filete--linha::before {
  top: 4px;
  height: 2px;
  background: linear-gradient(90deg, rgba(56, 232, 255, 0) 0%, rgba(56, 232, 255, .35) 50%, #38E8FF 86%, #EAFDFF 97%, rgba(56, 232, 255, 0) 100%);
}
vs-filete.vs-filete--linha::after {
  position: absolute;
  top: 4px;
  right: 0;
  left: 0;
  height: 2px;
  content: "";
  background: linear-gradient(90deg, rgba(56, 232, 255, .75), rgba(56, 232, 255, .25));
  opacity: 0;
  transition: opacity .3s ease;
}
vs-filete.vs-filete--linha.vs-filete--claro::before {
  background: linear-gradient(90deg, rgba(11, 92, 232, 0) 0%, rgba(11, 92, 232, .35) 50%, #0B5CE8 86%, #5B8CFF 97%, rgba(11, 92, 232, 0) 100%);
  filter: drop-shadow(0 0 4px rgba(56, 232, 255, .7));
}
vs-filete.vs-filete--linha.vs-filete--claro::after { background: linear-gradient(90deg, rgba(11, 92, 232, .7), rgba(11, 92, 232, .2)); }
.vs-cartao--aberto:hover > vs-filete.vs-filete--linha,
.vs-cartao--aberto:focus-within > vs-filete.vs-filete--linha { background-color: transparent; }
.vs-cartao--aberto:focus-within > vs-filete.vs-filete--linha::after { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  .vs-cartao--aberto:hover > vs-filete.vs-filete--linha::after { opacity: 1; }
}
.vs-medidor-vivo > .is-ativo { position: relative; overflow: hidden; }
.vs-medidor-vivo > .is-ativo::after {
  position: absolute;
  inset: 0;
  content: "";
  background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .9) 50%, rgba(255, 255, 255, 0) 100%);
  transform: translateX(-110%);
  animation: vs-barra-fluxo 2.4s ease-in-out infinite;
}
.vs-medidor-vivo > .is-ativo:nth-child(2)::after { animation-delay: .22s; }
.vs-medidor-vivo > .is-ativo:nth-child(3)::after { animation-delay: .44s; }
.vs-medidor-vivo > .is-ativo:nth-child(4)::after { animation-delay: .66s; }
/* W19q: no atalho "Comparar os quatro dossiês" (/sobre/, /metodologia/, /limites/, /relatorio/) as
   barras são pequenas e o brilho de cada uma corria quase junto com o das outras: lido como um
   piscar, o fluxo parecia parado. Aqui ele corre como um trilho: um pacote de luz atravessa a
   primeira barra acesa, depois a segunda, e assim por diante (3,2 s por volta, fora da faixa de 4 a
   6 s), com brilho mais forte. Só transform; nada de sombra ou filtro animados (M42).
   Correção 2: o pacote andava só 12,5% da volta e o atalho ficava parado ~1,6 s em cada volta (no
   calmo, ~3,6 s). Agora cada pacote atravessa a barra em 85% da volta, mais largo, e as barras saem
   0,4 s uma depois da outra: sempre há luz andando (com uma barra acesa, a pausa é de 0,48 s). */
.v-atalho .vs-medidor-vivo > .is-ativo::after {
  background: linear-gradient(90deg, rgba(234, 253, 255, 0) 0%, rgba(234, 253, 255, .9) 32%, #FFFFFF 50%, rgba(234, 253, 255, .9) 68%, rgba(234, 253, 255, 0) 100%);
  animation: vs-barra-trilho 3.2s linear infinite;
  animation-fill-mode: backwards; /* durante o atraso a luz espera fora da barra (sem brilho parado) */
}
.v-atalho .vs-medidor-vivo > .is-ativo:nth-child(2)::after { animation-delay: .4s; }
.v-atalho .vs-medidor-vivo > .is-ativo:nth-child(3)::after { animation-delay: .8s; }
.v-atalho .vs-medidor-vivo > .is-ativo:nth-child(4)::after { animation-delay: 1.2s; }
@keyframes vs-barra-trilho {
  0% { transform: translateX(-110%); }
  85%, 100% { transform: translateX(110%); }
}

/* 8. Cintilação rara de números, índices e marcas d'água: um alvo por vez,
   ativado por classe durante ~1 s; halo largo e fraco, sem sombra colada ao
   glifo.
   M42 (29/09/2026): o halo deixou de ser um filter: drop-shadow animado (que
   não roda no compositor e repintava o alvo a cada quadro). Agora é uma camada
   já pintada: um pseudo-elemento com o mesmo texto, sem cor própria
   (transparente), com o halo num text-shadow estático e atrás do glifo; só a
   opacidade dela anima (de 0 a 1 onde o alfa do filtro ia de 0 ao pico).
   Raio e alfa do text-shadow saíram da MEDIDA, não da conta: no Chrome 151 a
   conta "text-shadow 0 0 2R = drop-shadow(0 0 R)" dá ~metade da energia e
   um halo mais curto, porque a cauda fraca do text-shadow some no
   arredondamento de 8 bits; a resposta ao alfa anda em degraus e depende do
   tamanho do texto. Turno 15 (29/09/2026), energia do halo fora da caixa do
   alvo contra a produção W19g, picos de 10% e 40%, 1440 px:
   · 2 caracteres ("01"): 24 px .75 → 1,04–1,10; 30 px .72 → 1,00–1,03;
   · 3 ou mais (.vs-camada-longa: "CNPJ", "01 · 02"): 24 px .78 → 0,92–0,98;
     30 px .74 → 0,95–1,02; com os valores de 2 caracteres ficavam em 0,9 e 0,7.
   · índice de lista (camada única): 24 px .73 → 0,92–0,93; pico de .62 no
     segundo pulso → 0,93.
   Registro: _w19/revisao-rodada-visual/turno15/m42/sinais/.
   · .vs-camada (números em texto, vivo-sinais.js marca): ::before (antes, drop-shadow
     12 px, .5) e ::after (14 px, .42), com o texto em data-vs-brilho; o alvo vira bloco
     de contenção e contexto de empilhamento só durante a cintilação, como o
     filter antigo fazia.
   · .vs-ancora (índice de lista em ::before e marca d'água): ::after ancorado
     ao ::before (anchor positioning), com a fonte e o conteúdo copiados em
     variáveis --vs-b-*; o ::before continua o mesmo.
   · Sem as condições (caixa com borda ou fundo, pseudo já usado, navegador sem
     âncora), fica o filter antigo, que nenhuma página usa hoje. ------------- */
.vs-num.vs-cint:not(.vs-camada),
.vs-numeros > li.vs-cint:not(.vs-ancora)::before {
  animation: vs-cintilar 1.1s linear both;
}
:where(.vs-num.vs-camada.vs-cint) { position: relative; }
.vs-num.vs-camada.vs-cint { isolation: isolate; }
.vs-num.vs-camada.vs-cint::before,
.vs-num.vs-camada.vs-cint::after {
  position: absolute;
  inset: 0;
  z-index: -1;
  margin: 0;
  padding: inherit;
  border: 0;
  color: transparent;
  -webkit-text-fill-color: transparent;
  content: attr(data-vs-brilho) / "";
  opacity: 0;
  pointer-events: none;
  user-select: none;
}
.vs-num.vs-camada.vs-cint::before {
  text-shadow: 0 0 24px rgba(56, 232, 255, .75);
  animation: vs-cintilar-a 1.1s linear both;
}
.vs-num.vs-camada.vs-cint::after {
  text-shadow: 0 0 30px rgba(56, 232, 255, .72);
  animation: vs-cintilar-b 1.1s linear both;
}
.vs-num.vs-camada.vs-camada-longa.vs-cint::before { text-shadow: 0 0 24px rgba(56, 232, 255, .78); }
.vs-num.vs-camada.vs-camada-longa.vs-cint::after { text-shadow: 0 0 30px rgba(56, 232, 255, .74); }
/* Decodificação começando no meio: o halo da cópia ficaria fora do texto que corre.
   Resto raro: vivo-sinais.js não acende número com decodificação por fazer (COD-SINAIS-2);
   sobra a troca de modo (leve → completo) durante o 1,1 s da cintilação. */
.vs-num.vs-camada.vs-cint.vs-decod-ativo::before,
.vs-num.vs-camada.vs-cint.vs-decod-ativo::after { visibility: hidden; }
@keyframes vs-cintilar-a {
  0%, 22%, 100% { opacity: 0; }
  10% { opacity: 1; }
}
@keyframes vs-cintilar-b {
  0%, 22%, 70%, 100% { opacity: 0; }
  40% { opacity: 1; }
}
/* Âncora: ::after sobre a caixa do ::before (mesma largura, altura, recuo e
   fonte). Ordem de pintura igual à do filter antigo, que fazia do ::before um
   contexto de empilhamento no nível 0, acima do texto normal do item e abaixo
   do resto: o alvo vira bloco de contenção (o Chrome empilha o absoluto pelo
   bloco de contenção) e contexto de empilhamento; no item de lista o halo fica
   no nível 0 (acima do rótulo do item) e o ::before no nível 1 (acima do halo);
   na marca d'água (.env, já relative, filhos no nível 1) o ::after fica no
   nível 0, logo depois do ::before, como a marca antiga (sem isolar o .env). Item com decodificação por fazer não cintila
   (vivo-sinais.js), para a camada dela não mudar de referência no meio. */
:where(.vs-numeros > li.vs-ancora.vs-cint),
:where(.vs-numeros > li.vs-ancora.vs-cint)::before { position: relative; }
.vs-numeros > li.vs-ancora.vs-cint { isolation: isolate; }
.vs-numeros > li.vs-ancora.vs-cint::before,
.vs-cintila.vs-ancora.vs-cint::before { anchor-name: --vs-brilho; }
.vs-numeros > li.vs-ancora.vs-cint::before { z-index: 1; }
.vs-numeros > li.vs-ancora.vs-cint::after,
.vs-cintila.vs-ancora.vs-cint::after {
  position: absolute;
  top: anchor(--vs-brilho top);
  left: anchor(--vs-brilho left);
  z-index: -1;
  box-sizing: border-box;
  width: anchor-size(--vs-brilho width);
  height: anchor-size(--vs-brilho height);
  margin: 0;
  padding: var(--vs-b-padding-top) var(--vs-b-padding-right) var(--vs-b-padding-bottom) var(--vs-b-padding-left);
  border: 0;
  color: transparent;
  -webkit-text-fill-color: transparent;
  content: var(--vs-b-content);
  font-family: var(--vs-b-font-family);
  font-size: var(--vs-b-font-size);
  font-stretch: var(--vs-b-font-stretch);
  font-style: var(--vs-b-font-style);
  font-weight: var(--vs-b-font-weight);
  font-variant-numeric: var(--vs-b-font-variant-numeric);
  font-feature-settings: var(--vs-b-font-feature-settings);
  font-kerning: var(--vs-b-font-kerning);
  letter-spacing: var(--vs-b-letter-spacing);
  word-spacing: var(--vs-b-word-spacing);
  line-height: var(--vs-b-line-height);
  text-align: var(--vs-b-text-align);
  text-indent: var(--vs-b-text-indent);
  text-transform: var(--vs-b-text-transform);
  white-space: var(--vs-b-white-space);
  opacity: 0;
  pointer-events: none;
  user-select: none;
}
.vs-numeros > li.vs-ancora.vs-cint::after { z-index: 0; }
/* Índice de lista: uma camada só (antes 12 px, .5); no segundo pulso o raio
   fica o mesmo (era 14) e a opacidade de pico foi medida como a dos números. */
.vs-numeros > li.vs-ancora.vs-cint::after {
  text-shadow: 0 0 24px rgba(56, 232, 255, .73);
  animation: vs-cintilar-lista 1.1s linear both;
}
@keyframes vs-cintilar-lista {
  0%, 22%, 70%, 100% { opacity: 0; }
  10% { opacity: 1; }
  40% { opacity: .62; }
}
@keyframes vs-cintilar {
  0%, 100% { filter: drop-shadow(0 0 12px rgba(56, 232, 255, 0)); }
  10% { filter: drop-shadow(0 0 12px rgba(56, 232, 255, .5)); }
  22% { filter: drop-shadow(0 0 12px rgba(56, 232, 255, 0)); }
  40% { filter: drop-shadow(0 0 14px rgba(56, 232, 255, .42)); }
  70% { filter: drop-shadow(0 0 12px rgba(56, 232, 255, 0)); }
}
.vs-cintila { --vs-marca-op: .075; }
.secao--editorial-escura > .vs-cintila,
.sup-prova > .vs-cintila { --vs-marca-op: .12; }
@media (max-width: 720px) {
  .vs-cintila,
  .secao--editorial-escura > .vs-cintila,
  .sup-prova > .vs-cintila { --vs-marca-op: .06; }
}
.vs-cintila.vs-cint:not(.vs-ancora)::before { animation: vs-marca 1.2s linear both; }
/* Marca d'água com âncora. A marca é translúcida (opacidade o, de .06 a .22) e
   o filter antigo punha o halo (drop-shadow 18 px, alfa s) sob o glifo dentro
   do grupo dela: fora do glifo, o·s·halo; no glifo, o·cor, sem halo por baixo.
   Duas camadas com opacidade dão o mesmo resultado: o ::after (glifo na cor da
   marca, com o halo no text-shadow, por cima) com opacidade x = o·s/.8, e o
   ::before (só o glifo) com y = (o − x)/(1 − x), que compõem o·cor no glifo.
   Primeiro pulso: x = .22 e y = 0; segundo: x = .1275 e y = .0487 (raio de
   18 px no lugar de 14); em repouso, x = 0 e y = o. */
.vs-cintila.vs-ancora.vs-cint::before { animation: vs-marca-luz 1.2s linear both; }
.vs-cintila.vs-ancora.vs-cint::after {
  z-index: 0;
  color: var(--vs-b-color);
  -webkit-text-fill-color: var(--vs-b-color);
  text-shadow: 0 0 36px rgba(56, 232, 255, .92);
  animation: vs-marca-halo 1.2s linear both;
}
@keyframes vs-marca-luz {
  0%, 24%, 72%, 100% { opacity: var(--vs-marca-op, .075); }
  10% { opacity: 0; }
  42% { opacity: .0487; }
}
@keyframes vs-marca-halo {
  0%, 24%, 72%, 100% { opacity: 0; }
  10% { opacity: .22; }
  42% { opacity: .1275; }
}
@keyframes vs-marca {
  0%, 100% { opacity: var(--vs-marca-op, .075); filter: drop-shadow(0 0 18px rgba(56, 232, 255, 0)); }
  10% { opacity: .22; filter: drop-shadow(0 0 18px rgba(56, 232, 255, .8)); }
  24% { opacity: var(--vs-marca-op, .075); filter: drop-shadow(0 0 18px rgba(56, 232, 255, 0)); }
  42% { opacity: .17; filter: drop-shadow(0 0 14px rgba(56, 232, 255, .6)); }
  72% { opacity: var(--vs-marca-op, .075); filter: drop-shadow(0 0 18px rgba(56, 232, 255, 0)); }
}

/* 10. Selo de estado (.v-estado): sem sinal próprio. O ponto do componente
   fica parado em todos os modos (decisão P2 e critério M5). */

/* Fora da tela: animações contínuas pausadas. --------------------------------- */
.vs-pausa vs-cursor,
.vs-pausa > vs-reflexo::before,
.vs-pausa vs-barra::after,
.vs-pausa > vs-filete::before,
vs-filete.vs-pausa::before,
.vs-trilha.vs-pausa vs-trilho::before,
.vs-trilha.vs-pausa vs-etapa,
.vs-trilha.vs-pausa > li::after,
.vs-medidor-vivo.vs-pausa > .is-ativo::after {
  animation-play-state: paused !important;
}
/* Janela da conversa aberta (V05, classe posta por vivo.js): a página de trás fica sob o
   fundo escurecido; nenhuma animação dela continua gastando bateria. */
html.vivo-janela-aberta :is(main, .topo, .rodape) *,
html.vivo-janela-aberta :is(main, .topo, .rodape) *::before,
html.vivo-janela-aberta :is(main, .topo, .rodape) *::after {
  animation-play-state: paused !important;
}

/* Versão calma (html.vivo-calmo: movimento reduzido ou nível automático 2).
   Continuam a 0,45× (durações × 2,2) o cometa do cabeçalho, os filetes, o
   pacote das barras de fluxo e o pulso das trilhas; nenhum laço fica entre 4
   e 6 s. Desligados: cursor piscando, reflexos, cintilação, nós e
   anéis das trilhas, decodificação, ponta e pacote da barra de progresso (só
   o preenchimento segue a rolagem, P3), deslize do anel e seta que anda.
   Cada sinal calmo declara nome, duração, curva, atraso e repetição com
   seletor mais específico e !important: nenhum corte antigo sob movimento
   reduzido (o global de style.css ou o de uma página, como .experiencias *)
   o anula ou o deixa pela metade (M26). O estado de pausa fora da tela
   (animation-play-state) continua com as regras .vs-pausa. ---------------- */
html.vivo-calmo vs-topo-linha::before,
html.vivo-calmo vs-topo-linha::after {
  animation-name: vs-cometa-ida !important;
  animation-duration: 18.7s !important;
  animation-timing-function: linear !important;
  animation-delay: 0s !important;
  animation-iteration-count: infinite !important;
}
html.vivo-calmo vs-topo-linha::after { animation-name: vs-cometa-volta !important; }
html.vivo-calmo vs-filete::before {
  animation-name: vs-filete !important;
  animation-duration: 12.54s !important;
  animation-timing-function: var(--vs-curva-filete) !important;
  animation-delay: calc(var(--vs-atraso, 0s) * 2.2) !important;
  animation-iteration-count: infinite !important;
}
html.vivo-calmo vs-filete.vs-filete--cartao::before {
  animation-name: vs-cartao-sinal !important;
  animation-duration: 13.2s !important;
  animation-timing-function: linear !important;
  animation-delay: 0s !important;
}
html.vivo-calmo vs-trilho::before {
  animation-name: vs-trilho-v !important;
  animation-duration: calc(var(--vs-ciclo, 7.2s) * 2.2) !important;
  animation-timing-function: linear !important;
  animation-delay: 0s !important;
  animation-iteration-count: infinite !important;
}
html.vivo-calmo vs-trilho.vs-h::before { animation-name: vs-trilho-h !important; }
/* Barras de fluxo: o pacote atravessa em 2,4 s (0,45×) e descansa; o ciclo
   de 7,2 s fica fora da faixa de 4 a 6 s. */
html.vivo-calmo vs-barra::after,
html.vivo-calmo .vs-medidor-vivo > .is-ativo::after {
  animation-name: vs-barra-fluxo-calmo !important;
  animation-duration: 7.2s !important;
  animation-timing-function: ease-in-out !important;
  animation-delay: 0s !important;
  animation-iteration-count: infinite !important;
}
html.vivo-calmo vs-barra:nth-child(2)::after,
html.vivo-calmo .vs-medidor-vivo > .is-ativo:nth-child(2)::after { animation-delay: .48s !important; }
html.vivo-calmo vs-barra:nth-child(3)::after,
html.vivo-calmo .vs-medidor-vivo > .is-ativo:nth-child(3)::after { animation-delay: .97s !important; }
html.vivo-calmo .vs-medidor-vivo > .is-ativo:nth-child(4)::after { animation-delay: 1.45s !important; }
@keyframes vs-barra-fluxo-calmo {
  0% { transform: translateX(-110%); }
  33.3%, 100% { transform: translateX(110%); }
}
/* O trilho do atalho no calmo: a mesma ordem, 2,25× mais lento (7,2 s por volta; o pacote anda 6,1 s). */
html.vivo-calmo .v-atalho .vs-medidor-vivo > .is-ativo::after {
  animation-name: vs-barra-trilho !important;
  animation-duration: 7.2s !important;
  animation-timing-function: linear !important;
  animation-delay: 0s !important;
  animation-iteration-count: infinite !important;
}
html.vivo-calmo .v-atalho .vs-medidor-vivo > .is-ativo:nth-child(2)::after { animation-delay: .9s !important; }
html.vivo-calmo .v-atalho .vs-medidor-vivo > .is-ativo:nth-child(3)::after { animation-delay: 1.8s !important; }
html.vivo-calmo .v-atalho .vs-medidor-vivo > .is-ativo:nth-child(4)::after { animation-delay: 2.7s !important; }
html.vivo-calmo vs-cursor,
html.vivo-calmo .vs-trilha--nos > li::after,
html.vivo-calmo .vs-num.vs-cint,
html.vivo-calmo .vs-numeros > li.vs-cint::before,
html.vivo-calmo .vs-cintila.vs-cint::before,
html.vivo-calmo :is(.vs-num, .vs-numeros > li, .vs-cintila).vs-cint::before,
html.vivo-calmo :is(.vs-num, .vs-numeros > li, .vs-cintila).vs-cint::after { animation: none !important; }
html.vivo-calmo vs-cursor { opacity: .95; }
html.vivo-calmo vs-reflexo,
html.vivo-calmo vs-etapa,
html.vivo-calmo vs-progresso-ponta,
html.vivo-calmo vs-progresso-cheio::after { display: none; }
html.vivo-calmo vs-brilho::before { transition: none; }
html.vivo-calmo .vs-seta::after { transform: none !important; transition: none; }

/* Quieto (html.vivo-quieto: só a pausa do usuário; desde o turno 15 o nível
   automático tem teto no calmo e desce com a página fluida; a classe
   vivo-parado vale igual, por compatibilidade): quadro final fixo e
   determinístico; nenhuma animação nem transição, nem no hover ou foco; a
   barra de progresso some (nada segue a rolagem). ------------------------ */
html:is(.vivo-quieto, .vivo-parado) vs-cursor,
html:is(.vivo-quieto, .vivo-parado) vs-topo-linha::before,
html:is(.vivo-quieto, .vivo-parado) vs-topo-linha::after,
html:is(.vivo-quieto, .vivo-parado) vs-filete::before,
html:is(.vivo-quieto, .vivo-parado) vs-trilho::before,
html:is(.vivo-quieto, .vivo-parado) .vs-trilha--nos > li::after,
html:is(.vivo-quieto, .vivo-parado) .vs-num.vs-cint,
html:is(.vivo-quieto, .vivo-parado) .vs-numeros > li.vs-cint::before,
html:is(.vivo-quieto, .vivo-parado) .vs-cintila.vs-cint::before,
html:is(.vivo-quieto, .vivo-parado) :is(.vs-num, .vs-numeros > li, .vs-cintila).vs-cint::before,
html:is(.vivo-quieto, .vivo-parado) :is(.vs-num, .vs-numeros > li, .vs-cintila).vs-cint::after { animation: none !important; }
html:is(.vivo-quieto, .vivo-parado) vs-reflexo,
html:is(.vivo-quieto, .vivo-parado) vs-progresso,
html:is(.vivo-quieto, .vivo-parado) vs-etapa,
html:is(.vivo-quieto, .vivo-parado) vs-barra::after,
html:is(.vivo-quieto, .vivo-parado) .vs-medidor-vivo > .is-ativo::after { display: none; }
html:is(.vivo-quieto, .vivo-parado) vs-brilho,
html:is(.vivo-quieto, .vivo-parado) vs-brilho::before,
html:is(.vivo-quieto, .vivo-parado) vs-topo-linha,
html:is(.vivo-quieto, .vivo-parado) vs-filete,
html:is(.vivo-quieto, .vivo-parado) vs-filete.vs-filete--linha::after { transition: none !important; }
html:is(.vivo-quieto, .vivo-parado) .vs-seta::after { transform: none !important; transition: none !important; }
html:is(.vivo-quieto, .vivo-parado) vs-cursor { opacity: .95; }
html:is(.vivo-quieto, .vivo-parado) vs-topo-linha.vs-dorme { opacity: 1; }
html:is(.vivo-quieto, .vivo-parado) vs-topo-linha::before { transform: translateX(345%); }
html:is(.vivo-quieto, .vivo-parado) vs-topo-linha::after { transform: translateX(269%); }
html:is(.vivo-quieto, .vivo-parado) vs-filete::before { transform: translateX(82%); }
html:is(.vivo-quieto, .vivo-parado) vs-filete.vs-filete--cartao::before { transform: none; }
/* Linha das aplicações: o cometa parado logo depois do traço de destaque. */
html:is(.vivo-quieto, .vivo-parado) vs-filete.vs-filete--linha::before { transform: translateX(-18%); }
/* Trilha: a linha acesa a partir do primeiro selo, esmaecendo no eixo. */
html:is(.vivo-quieto, .vivo-parado) vs-trilho::before {
  background-image: linear-gradient(180deg, var(--vs-p-fixo) 0%, var(--vs-p-fixo-2) 45%, rgba(56, 232, 255, 0) 100%);
  background-position: 50% 0;
  background-size: 3px 100%;
  filter: none;
  transform: none;
}
html:is(.vivo-quieto, .vivo-parado) vs-trilho.vs-h::before {
  background-image: linear-gradient(90deg, var(--vs-p-fixo) 0%, var(--vs-p-fixo-2) 45%, rgba(56, 232, 255, 0) 100%);
  background-position: 0 50%;
  background-size: 100% 3px;
  transform: none;
}
html:is(.vivo-quieto, .vivo-parado) .vs-trilha--nos > li:first-child::after { opacity: 1; box-shadow: 0 0 10px rgba(56, 232, 255, .8); }

/* Movimento reduzido sem classe de modo (vivo.js sem o contrato ou fora do
   ar): nada contínuo. As peças que correm somem, porque o corte global de
   style.css deixaria cada laço em 0,01 ms, pulando de lugar a cada quadro. */
@media (prefers-reduced-motion: reduce) {
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) vs-cursor,
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) .vs-trilha--nos > li::after,
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) .vs-num.vs-cint,
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) .vs-numeros > li.vs-cint::before,
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) .vs-cintila.vs-cint::before,
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) :is(.vs-num, .vs-numeros > li, .vs-cintila).vs-cint::before,
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) :is(.vs-num, .vs-numeros > li, .vs-cintila).vs-cint::after { animation: none !important; }
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) :is(vs-reflexo, vs-topo-linha, vs-progresso-ponta, vs-filete, vs-trilho, vs-etapa),
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) vs-progresso-cheio::after,
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) vs-barra::after,
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) .vs-medidor-vivo > .is-ativo::after { display: none; }
  html:not(.vivo-calmo):not(.vivo-quieto):not(.vivo-parado) .vs-seta::after { transform: none !important; }
}

/* Cores forçadas (alto contraste do sistema): a camada some em qualquer modo;
   o anel viraria um contorno sólido piscando e os brilhos, blocos opacos. -- */
@media (forced-colors: active) {
  vs-decod,
  vs-cursor,
  vs-brilho,
  vs-reflexo,
  vs-topo-linha,
  vs-progresso,
  vs-etapa,
  vs-trilho,
  vs-filete,
  vs-medidor { display: none !important; }
  .vs-trilha--nos > li::after,
  .vs-medidor-vivo > .is-ativo::after { display: none; }
  .vs-num.vs-cint,
  .vs-numeros > li.vs-cint::before,
  .vs-cintila.vs-cint::before { animation: none !important; }
  /* As camadas do halo (M42): o texto transparente viraria CanvasText. */
  .vs-camada::before,
  .vs-camada::after,
  .vs-ancora::after { display: none !important; }
  .vs-seta:hover,
  .vs-seta:focus-visible { background-image: none !important; }
  .vs-seta::after { transform: none !important; }
}

/* Mais contraste pedido pelo sistema (opcional, M33), em qualquer modo: some o
   que passa atrás do texto (holofote, brilho interno, ruído com
   halo), nada cintila e não há decodificação (vivo-sinais.js). Cartões e
   botões ganham borda sólida e parada: o anel da borda fica aceso numa cor
   só (cartões) ou na cor do texto (botões), sem o reflexo que corre. ------ */
@media (prefers-contrast: more) {
  vs-brilho::after,
  vs-holofote { display: none !important; }
  vs-brilho { opacity: 1; box-shadow: none !important; }
  vs-brilho::before { background: #5B8CFF !important; transition: none; }
  .vs-cartao--claro > vs-brilho::before { background: #0B5CE8 !important; }
  vs-reflexo,
  html:is(.vivo-calmo, .vivo-quieto, .vivo-parado) vs-reflexo { display: block; background: currentcolor; }
  vs-reflexo::before { display: none; }
  vs-ruido { text-shadow: none !important; }
  .vs-num.vs-cint,
  .vs-numeros > li.vs-cint::before,
  .vs-cintila.vs-cint::before,
  :is(.vs-num, .vs-numeros > li, .vs-cintila).vs-cint::before,
  :is(.vs-num, .vs-numeros > li, .vs-cintila).vs-cint::after { animation: none !important; }
  .vs-cintila { --vs-marca-op: .05; }
}

/* W19, ACS-05: em telas largas o lançador da conversa é filho direto do <body>; as órbitas
   dele também param com a janela aberta. P6 (spec §2.3.6, revisão C2-05): só o acionador para,
   com animation: none e o quadro fixo do pausado; o emblema de carregamento, dentro da janela,
   segue o modo em vigor (senão a cascata nunca rodaria). */
html.vivo-janela-aberta .videre-assistant-launcher :is(.va-orbita, .va-plano, .va-anel, .va-halo, .va-v-luz),
html.vivo-janela-aberta .videre-assistant-launcher .va-trilha::before { animation: none !important; }
html.vivo-janela-aberta .videre-assistant-launcher .va-orbita--a { transform: rotate(40deg); }
html.vivo-janela-aberta .videre-assistant-launcher .va-orbita--b { transform: rotate(-150deg); }
html.vivo-janela-aberta .videre-assistant-launcher .va-orbita--c { transform: rotate(110deg); }
html.vivo-janela-aberta .videre-assistant-launcher .va-halo { opacity: .2; transform: none; }
html.vivo-janela-aberta .videre-assistant-launcher .va-v-luz { opacity: .6; }

/* W19 · P5 (28/09/2026, spec-P5-futurista.md E1-07 e E2-10): luz correndo na borda de cima do
   painel da trilha do herói e dos dois cartões da dobra 2 da Home. O ponto quente do filete do
   pé da dobra 2 (E2-09) saiu com os fundos de linhas (raia FUNDO, 29/09). Só transform
   (M8/M44); todos os laços fora da faixa de 4 a 6 s (M23): 7,2 s nos cartões (15,8 s no calmo)
   e 11 s no herói (24 s no calmo). Pausado e quieto: os cometas ficam fora da vista (sem luz),
   o quadro do conceito. Fora da tela, .vs-pausa;
   janela da conversa aberta, cores forçadas e movimento reduzido sem modo: regras gerais acima.
   Os tokens --fx-* só existem na Home: cada um leva reserva literal. */
/* W19q r3: o cometa corre só no trecho reto da borda de cima, recuado o raio do painel dos dois lados
   (--vs-recuo, posto pelo vivo-sinais.js a partir do raio lido; 18 px de reserva): antes ele ia de
   ponta a ponta e passava por fora da curva dos cantos. */
vs-filete.vs-filete--console,
vs-filete.vs-filete--heroi {
  right: var(--vs-recuo, 18px);
  left: var(--vs-recuo, 18px);
  border-radius: 0;
}
vs-filete.vs-filete--console::before { animation-duration: 7.2s; }
vs-filete.vs-filete--heroi::before { animation-duration: var(--fx-t-cometa, 11s); }
/* O herói só tem o efeito a partir de 721 px (o celular não tem o painel de vidro). */
@media (max-width: 720px) {
  vs-filete.vs-filete--heroi { display: none; }
}
html.vivo-calmo vs-filete.vs-filete--console::before { animation-duration: 15.8s !important; }
html.vivo-calmo vs-filete.vs-filete--heroi::before { animation-duration: 24s !important; }
html:is(.vivo-quieto, .vivo-parado) :is(vs-filete.vs-filete--console, vs-filete.vs-filete--heroi)::before { transform: translateX(-115%); }
