
/* ═══════════════════════════════════════════════ apresentação · tokens
   A base é a TELA DE LOGIN (estilo.py §login): noite azul com curvas de
   luz, o cartão de vidro como única superfície, o botão azul com brilho.
   Os valores são copiados e não importados — esta página é servida antes
   de qualquer sessão e não deve arrastar a folha de 85 KB do aplicativo
   só para pintar um fundo.

   Quem chega aqui e clica em "Entrar" cai na mesma noite, no mesmo azul,
   com o mesmo cartão. Era a emenda que faltava: a landing era preta e
   cinza, e o login, azul-marinho. */
:root{
  --bg:#020713;
  --bg-2:#071227;
  --campo:rgba(4,11,28,.62);
  --borda:rgba(86,150,255,.30);
  --borda-sutil:rgba(130,160,210,.18);
  --tx1:#F2F6FC;
  --tx2:#B6C2D6;
  --tx3:#8C99B0;
  --azul:#4AA8FF;
  --azul-claro:#8CC8FF;
  --azul-fraco:rgba(31,139,255,.10);
  --azul-borda:rgba(77,155,255,.30);
  --sobre-acento:#FFFFFF;
  --ok:#4ADE80;
  --alerta:#F2B457;
  --erro:#FF6B6B;
  --roxo:#B79CFF;
  --r-md:10px;
  --r-lg:16px;
  --r-xl:20px;
  --r-pill:999px;
  --sans:-apple-system,BlinkMacSystemFont,"SF Pro Display","SF Pro Text",
         "Segoe UI Variable","Segoe UI","Inter",Roboto,"Helvetica Neue",
         Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono","JetBrains Mono",Menlo,
         Consolas,monospace;
  /* A curva de todo movimento desta página — a mesma `--lg-sai` do login. */
  --curva:cubic-bezier(.16,1,.3,1);
  /* A superfície: o cartão do login, com o mesmo vidro e o mesmo halo. */
  --vidro:linear-gradient(158deg,rgba(46,98,200,.30) 0%,
          rgba(13,28,62,.55) 36%,rgba(5,12,30,.74) 100%);
  --vidro-sombra:0 32px 80px -24px rgba(0,0,0,.8),
                 0 0 70px -12px rgba(30,110,255,.28),
                 inset 0 1px 0 rgba(170,205,255,.14);
  --grad-btn:linear-gradient(180deg,#2696FF,#0A68F2);
  --sombra-btn:0 12px 28px -12px rgba(14,110,255,.85),
               inset 0 1px 0 rgba(255,255,255,.24);
  --largura:1180px;
}

/* ══════════════════════════════════════════════════════════════ base */
*{box-sizing:border-box}
/* O fundo no <html>, e não só no body: entre a navegação e a primeira
   pintura o navegador mostra o fundo da RAIZ, e claro ali é o flash que o
   commit f9f4cc1 já teve de corrigir uma vez no aplicativo. */
html{background:#020713;scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  margin:0;background:transparent;color:var(--tx1);
  font:400 17px/1.55 var(--sans);
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;caret-color:#6FB4FF;
}
h1,h2,h3{margin:0;font-weight:700;letter-spacing:-.03em;line-height:1.06}
p{margin:0}
a{color:var(--azul);text-decoration:none}
a:hover{color:var(--azul-claro)}
:focus-visible{outline:2px solid #8CC8FF;outline-offset:3px;border-radius:6px}
svg{display:block}
::selection{background:rgba(31,139,255,.45);color:#fff}

.ap-pular{
  position:absolute;left:-9999px;top:0;z-index:60;
  background:var(--grad-btn);color:#fff;
  padding:10px 16px;border-radius:0 0 var(--r-md) 0;font-weight:600;
}
.ap-pular:focus{left:0}

.ap-larg{width:min(100% - 48px,var(--largura));margin-inline:auto}
@media (max-width:640px){.ap-larg{width:calc(100% - 32px)}}

/* ══════════════════════════════════════ o fundo: a noite do login
   Copiado de `estilo.py` §login (`.fundo-login`), e pela mesma razão que
   a paleta. A regra que importa está no original e vale aqui: SÓ
   `transform` e `opacity` animam em laço, e o desfoque do brilho é
   ESTÁTICO, dentro de um filtro SVG num grupo parado.

   A versão anterior desta página fazia o contrário — três manchas
   animando `transform` dentro de um `filter:blur(90px)` — e o navegador
   re-rasterizava a camada inteira a cada quadro: o fundo piscava.
   Medido: 13 quadros distintos em 14 amostras, contra 1 depois. */
.fundo-login{
  position:fixed;inset:0;z-index:-1;overflow:hidden;pointer-events:none;
  background:radial-gradient(55% 50% at 86% 46%,rgba(16,64,170,.42),transparent 72%),
    radial-gradient(50% 45% at 14% 8%,rgba(14,44,130,.4),transparent 72%),
    linear-gradient(180deg,#030B1F,#010409);
}
.fl-luz{
  position:absolute;width:75vmax;height:75vmax;border-radius:50%;
  background:radial-gradient(closest-side,rgba(28,96,235,.26),transparent);
}
.fl-luz-a{left:-28vmax;top:-30vmax}
.fl-luz-b{right:-30vmax;top:5vh}
.fl-camada{position:absolute;inset:-4%}
.fl-c1{--prof:-14px;transform-origin:0 0}
.fl-c2{--prof:-22px;transform-origin:100% 100%}
.fl-camada svg{
  position:absolute;inset:0;width:100%;height:100%;
  transform:translate3d(calc(var(--px,0) * var(--prof)),
            calc(var(--py,0) * var(--prof)),0);
  transition:transform 1.4s var(--curva);
}
/* Os cometas: um traço curto que percorre a curva e some por um tempo. */
.fl-cometas{will-change:transform}
.fl-cometa{
  fill:none;stroke:#D2EAFF;stroke-width:2.4;stroke-linecap:round;
  stroke-dasharray:60 1940;stroke-dashoffset:60;display:none;
}

/* ═════════════════════════════════════════════════════════════ topo */
.ap-topo{
  position:sticky;top:0;z-index:50;
  height:52px;
  background:rgba(2,7,19,.72);
  border-bottom:1px solid transparent;
  -webkit-backdrop-filter:saturate(160%) blur(18px);
  backdrop-filter:saturate(160%) blur(18px);
  transition:border-color .35s var(--curva),background .35s var(--curva);
}
.ap-topo.rolou{background:rgba(2,7,19,.9);
  border-bottom-color:rgba(86,150,255,.2)}
.ap-topo-in{display:flex;align-items:center;gap:18px;height:100%}
.ap-marca{display:flex;align-items:center;gap:10px;color:var(--tx1)}
.ap-marca:hover{color:var(--tx1)}
/* O emblema é o do login: o quadrado azul com o glifo do pulso, no mesmo
   gradiente e com o mesmo brilho. */
.ap-logo{
  width:30px;height:30px;flex:none;border-radius:9px;
  display:grid;place-items:center;color:#fff;
  background:linear-gradient(160deg,#35AEFF,#0A6CF5);
  box-shadow:0 10px 24px -10px rgba(20,125,255,.7),
             inset 0 1px 0 rgba(255,255,255,.3);
  transition:transform .3s var(--curva),box-shadow .3s var(--curva);
}
.ap-logo svg{width:17px;height:17px}
.ap-marca:hover .ap-logo{
  transform:translateY(-1px) scale(1.05);
  box-shadow:0 14px 30px -10px rgba(20,125,255,.85),
             inset 0 1px 0 rgba(255,255,255,.4);
}
.ap-marca-txt{display:block;line-height:1.15}
.ap-marca b{display:block;font-size:14.5px;letter-spacing:-.015em;font-weight:650}
.ap-marca-sub{display:block;font-size:10.5px;color:var(--tx3);letter-spacing:.02em}
.ap-nav{display:flex;gap:2px;margin-left:auto;margin-right:auto}
.ap-nav a{
  position:relative;color:var(--tx2);font-size:13px;padding:7px 12px;
  border-radius:var(--r-md);letter-spacing:-.005em;
  transition:color .18s ease-out,background .18s ease-out;
}
.ap-nav a::after{
  content:"";position:absolute;left:12px;right:12px;bottom:3px;height:1px;
  background:var(--azul);transform:scaleX(0);
  transition:transform .3s var(--curva);
}
.ap-nav a:hover{color:var(--tx1)}
.ap-nav a:hover::after{transform:scaleX(1)}
.ap-espaco{flex:1}
.ap-nav + .ap-espaco{display:none}

/* Os dois botões da barra: o mesmo par do login — o azul com brilho, e o
   campo escuro de borda fria. */
.ap-entrar{
  display:inline-flex;align-items:center;gap:7px;
  height:34px;padding:0 15px;border-radius:var(--r-md);
  background:var(--grad-btn);color:#fff;
  font-size:13.5px;font-weight:600;letter-spacing:-.01em;
  border:1px solid rgba(130,190,255,.3);box-shadow:var(--sombra-btn);
  transition:filter .25s ease,box-shadow .3s ease,transform .25s var(--curva);
}
.ap-entrar:hover{
  color:#fff;filter:brightness(1.1);transform:translateY(-1px);
  box-shadow:0 18px 36px -14px rgba(14,110,255,.95),
             inset 0 1px 0 rgba(255,255,255,.28);
}
.ap-entrar:active{transform:translateY(0) scale(.99);filter:brightness(.94)}
.ap-entrar svg{width:14px;height:14px;transition:transform .3s var(--curva)}
.ap-entrar:hover svg{transform:translateX(3px)}

.ap-demo-topo{
  display:inline-flex;align-items:center;height:34px;padding:0 14px;
  border-radius:var(--r-md);font-size:13px;font-weight:540;
  color:var(--tx2);background:var(--campo);
  border:1px solid rgba(130,160,210,.24);
  transition:color .2s ease,background .25s ease,border-color .25s ease;
}
.ap-demo-topo:hover{color:var(--tx1);border-color:rgba(140,175,230,.4)}

.ap-menu{display:none;position:relative;margin-left:auto}
.ap-menu > summary{
  list-style:none;cursor:pointer;width:36px;height:34px;border-radius:var(--r-md);
  display:grid;place-items:center;color:var(--tx1);
  background:var(--campo);border:1px solid rgba(130,160,210,.24);
}
.ap-menu > summary::-webkit-details-marker{display:none}
.ap-menu > summary svg{width:17px;height:17px}
.ap-menu[open] > summary{border-color:rgba(77,155,255,.6)}
.ap-menu-cx{
  position:absolute;right:0;top:42px;min-width:218px;padding:8px;
  border-radius:var(--r-lg);background:var(--vidro);
  border:1px solid var(--borda);box-shadow:var(--vidro-sombra);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  backdrop-filter:blur(18px) saturate(140%);
  display:grid;gap:2px;
}
.ap-menu-cx a{display:block;padding:11px 13px;border-radius:var(--r-md);
  color:var(--tx2);font-size:14.5px}
.ap-menu-cx a:hover{background:rgba(120,160,230,.12);color:var(--tx1)}
.ap-menu-cx .ap-menu-cta{
  margin-top:6px;background:var(--grad-btn);color:#fff;
  font-weight:600;text-align:center;box-shadow:var(--sombra-btn);
}
.ap-menu-cx .ap-menu-cta:hover{color:#fff;filter:brightness(1.1)}

@media (max-width:1020px){
  .ap-nav{display:none}.ap-demo-topo{display:none}
  .ap-menu{display:block}
  .ap-topo-in{gap:10px}
}
@media (max-width:420px){.ap-marca-sub{display:none}}

/* ════════════════════════════════════════════════════════════ hero
   Assimétrico de propósito: o texto ancora à esquerda e o aparelho ocupa
   a direita. Uma landing centrada do começo ao fim é o que faz todas
   elas parecerem a mesma. */
.ap-hero{position:relative;padding:96px 0 40px}
@media (max-width:640px){.ap-hero{padding:56px 0 24px}}
.ap-hero-in{
  display:grid;grid-template-columns:minmax(0,.84fr) minmax(0,1.16fr);
  gap:56px;align-items:center;
}
@media (max-width:1100px){.ap-hero-in{grid-template-columns:1fr;gap:40px}}

.ap-selo{
  display:inline-flex;align-items:center;gap:9px;
  height:34px;padding:0 15px 0 12px;border-radius:var(--r-pill);
  background:var(--campo);border:1px solid rgba(130,160,210,.24);
  color:var(--tx2);font-size:12.5px;letter-spacing:.01em;
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
}
.ap-selo b{color:var(--tx1);font-weight:600;white-space:nowrap}
.ap-ponto{
  width:7px;height:7px;border-radius:50%;background:var(--ok);flex:none;
  box-shadow:0 0 0 4px rgba(74,222,128,.16);
  animation:ap-pulso 2.6s ease-in-out infinite;
}
@keyframes ap-pulso{50%{box-shadow:0 0 0 9px rgba(74,222,128,0)}}

.ap-h1{
  margin:26px 0 0;
  font-size:clamp(40px,4.4vw,66px);
  letter-spacing:-.05em;line-height:1;font-weight:700;
  max-width:11ch;
}
.ap-h1,.ap-h2,.ap-sub{text-wrap:balance}
.ap-brilho{
  background:linear-gradient(94deg,#DCEBFF 0%,#5AA8FF 48%,#9CCFFF 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  background-size:200% 100%;
  animation:ap-brilho 9s ease-in-out infinite alternate;
}
@keyframes ap-brilho{to{background-position:100% 0}}
.ap-sub{
  margin:34px 0 0;max-width:40ch;
  font-size:clamp(17px,1.5vw,20px);line-height:1.5;color:var(--tx2);
  letter-spacing:-.012em;font-weight:440;
}
.ap-sub b{color:var(--tx1);font-weight:560}
.ap-acoes{display:flex;flex-wrap:wrap;gap:12px;margin-top:32px}
.ap-btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  height:52px;padding:0 26px;border-radius:12px;
  font-size:16px;font-weight:600;letter-spacing:-.01em;
}
.ap-btn svg{width:18px;height:18px;transition:transform .3s var(--curva)}
.ap-btn-1{
  background:var(--grad-btn);color:#fff;
  border:1px solid rgba(130,190,255,.3);box-shadow:var(--sombra-btn);
  transition:filter .25s ease,box-shadow .3s ease,transform .25s var(--curva);
}
.ap-btn-1:hover{
  color:#fff;filter:brightness(1.1);transform:translateY(-1px);
  box-shadow:0 18px 36px -14px rgba(14,110,255,.95),
             inset 0 1px 0 rgba(255,255,255,.28);
}
.ap-btn-1:active{transform:translateY(0) scale(.99);filter:brightness(.94)}
.ap-btn-1:hover svg{transform:translateX(3px)}
.ap-btn-2{
  background:var(--campo);color:var(--tx1);
  border:1px solid rgba(130,160,210,.24);
  transition:border-color .25s ease,background-color .25s ease,
             transform .25s var(--curva);
}
.ap-btn-2:hover{color:var(--tx1);border-color:rgba(140,175,230,.4);
  background-color:rgba(5,14,36,.78);transform:translateY(-1px)}
.ap-btn-2:hover svg{transform:translateY(3px)}

/* ═════════════════════════════════════ o aparelho do hero · a operação
   A janela do próprio produto — o mesmo vidro do cartão de login —, em
   perspectiva, encenando UMA execução em sete batidas: os equipamentos
   aparecem, um grupo é selecionado, o plano é preparado, a execução
   começa, a luz atravessa os fios, os resultados chegam um a um e o
   console fecha a conta. As batidas são classes cumulativas (`b1`…`b7`)
   postas pelo script; sem script a cena nasce no estado final. */
.ap-tela{position:relative;perspective:1800px;min-width:0}
.ap-janela{
  position:relative;z-index:1;border-radius:var(--r-xl);
  background:var(--vidro);border:1px solid var(--borda);
  box-shadow:var(--vidro-sombra);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  backdrop-filter:blur(18px) saturate(140%);
  overflow:hidden;transform-origin:50% 0;will-change:transform;
}
.ap-janela-topo{
  display:flex;align-items:center;gap:8px;height:42px;padding:0 15px;
  border-bottom:1px solid rgba(130,160,210,.14);background:rgba(2,7,19,.3);
}
.ap-bolha{width:10px;height:10px;border-radius:50%;background:#2B3B5C}
.ap-bolha:nth-child(1){background:#FF5F57}
.ap-bolha:nth-child(2){background:#FEBC2E}
.ap-bolha:nth-child(3){background:#28C840}
.ap-url{
  margin:0 auto;display:inline-flex;align-items:center;gap:7px;
  height:26px;padding:0 12px;border-radius:8px;
  background:var(--campo);border:1px solid rgba(130,160,210,.18);
  font:500 11.5px/1 var(--mono);color:var(--tx3);letter-spacing:.01em;
}
.ap-url svg{width:11px;height:11px;color:var(--ok)}
.ap-url b{color:var(--tx2);font-weight:500}
.ap-app{display:grid;grid-template-columns:190px 1fr;min-height:376px}
.ap-lateral{
  border-right:1px solid rgba(130,160,210,.14);padding:12px 9px;
  background:rgba(2,7,19,.28);font-size:12.5px;
}
.ap-lateral-tit{
  font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--tx3);padding:6px 10px;
}
.ap-lateral span.it{
  display:flex;align-items:center;gap:9px;height:28px;padding:0 10px;
  border-radius:8px;color:var(--tx2);
}
.ap-lateral .it svg{width:14px;height:14px;opacity:.8}
.ap-lateral .it.on{background:rgba(31,139,255,.16);color:var(--tx1)}
.ap-lateral .it.on svg{color:var(--azul-claro);opacity:1}
.ap-lateral .it em{
  margin-left:auto;font-style:normal;font:500 10px/1 var(--mono);
  color:var(--tx3);background:rgba(120,160,230,.1);padding:3px 6px;
  border-radius:6px;
}
.ap-conteudo{display:flex;flex-direction:column;min-width:0}
.ap-conteudo-topo{
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  padding:12px 18px;border-bottom:1px solid rgba(130,160,210,.14);
}
.ap-conteudo-topo h4{margin:0;font-size:13.5px;font-weight:600;letter-spacing:-.01em}
.ap-chip{
  display:inline-flex;align-items:center;height:22px;padding:0 9px;
  border-radius:7px;font:500 11px/1 var(--mono);color:var(--tx2);
  background:var(--campo);border:1px solid rgba(130,160,210,.2);
}
.ap-chip.ok{color:var(--ok);background:rgba(74,222,128,.1);
  border-color:rgba(74,222,128,.26)}
.ap-chip.al{color:var(--alerta);background:rgba(242,180,87,.1);
  border-color:rgba(242,180,87,.26)}
.ap-chip.vivo::before{
  content:"";width:6px;height:6px;border-radius:50%;background:var(--ok);
  margin-right:6px;animation:ap-pulso 1.8s ease-in-out infinite;
}
.ap-conteudo-topo .ap-chip.vivo{margin-left:auto}

/* a malha: o coletor à esquerda, oito equipamentos à direita */
.ap-op{display:flex;flex-direction:column;flex:1;min-width:0}
.ap-malha{width:100%;height:auto;padding:10px 14px 0;font-family:var(--mono)}
.ap-malha .cx{fill:rgba(10,24,54,.55);stroke:rgba(130,160,210,.22)}
.ap-malha .hub{fill:rgba(74,222,128,.08);stroke:rgba(74,222,128,.34)}
.ap-malha .rot{fill:#8C99B0;font-size:9px;letter-spacing:.1em}
.ap-malha .nome{fill:#CBD8EC;font-size:10.5px}
.ap-malha .st{fill:#8C99B0;font-size:9.5px}
.ap-malha .st.ok{fill:#4ADE80}
.ap-malha .st.al{fill:#F2B457}
.ap-malha .pt{fill:#2B3B5C}
.ap-malha .no.ok .pt{fill:#4ADE80}
.ap-malha .no.al .pt{fill:#F2B457}
.ap-malha .fio{stroke:#4AA8FF;stroke-width:1.1;fill:none;opacity:.5}
.ap-malha .anel{display:none;fill:none;stroke:#4AA8FF;stroke-width:1.2;opacity:.75}
.ap-malha .faisca{display:none;stroke:#9CCFFF;stroke-width:2;fill:none;
  stroke-linecap:round;stroke-dasharray:22 560}
.ap-malha .plano rect{fill:rgba(31,139,255,.16);stroke:rgba(77,155,255,.45)}
.ap-malha .plano text{fill:#9CCFFF;font-size:9.5px}
.ap-malha .halo{display:none;fill:none;stroke:#4ADE80;stroke-width:1}

/* o console do hero: a mesma operação pela linha de comando.
   A ALTURA É FIXA. Com `min-height`, as quatro linhas entrando a cada
   volta do laço faziam a janela crescer 43 px e o documento inteiro
   pular — medido: 7416 / 7437 / 7458. */
.ap-term{
  padding:10px 16px 14px;font:12px/1.75 var(--mono);
  border-top:1px solid rgba(130,160,210,.14);background:rgba(1,5,14,.5);
  white-space:pre-wrap;word-break:break-word;
  height:108px;overflow:hidden;
}
.ap-term .l{display:block}
.ap-term .pr{color:var(--azul)}
.ap-term .ok{color:var(--ok)}
.ap-term .al{color:var(--alerta)}
.ap-term .cz{color:var(--tx3)}
.ap-cursor{
  display:inline-block;width:7px;height:14px;vertical-align:-2px;
  background:var(--azul);margin-left:2px;animation:ap-pisca 1.05s steps(2) infinite;
}
@keyframes ap-pisca{50%{opacity:0}}

/* os controles do hero: pausar a sequência e ver em que batida ela está */
.ap-hctrl{display:flex;align-items:center;gap:12px;margin-top:18px}
.ap-hctrl[hidden]{display:none}
.ap-pausa{
  display:inline-flex;align-items:center;gap:8px;height:34px;padding:0 14px;
  border-radius:var(--r-md);cursor:pointer;
  font:600 12.5px/1 var(--sans);letter-spacing:-.01em;color:var(--tx2);
  background:var(--campo);border:1px solid rgba(130,160,210,.24);
  transition:color .2s ease,border-color .25s ease,background-color .25s ease;
}
.ap-pausa:hover{color:var(--tx1);border-color:rgba(140,175,230,.4);
  background-color:rgba(5,14,36,.78)}
.ap-pausa svg{width:11px;height:11px;color:var(--azul)}
.ap-pausa .ap-ic-play{display:none}
.ap-pausa[aria-pressed="true"] .ap-ic-play{display:block}
.ap-pausa[aria-pressed="true"] .ap-ic-pausa{display:none}
.ap-pausa .ap-t-play{display:none}
.ap-pausa[aria-pressed="true"] .ap-t-play{display:inline}
.ap-pausa[aria-pressed="true"] .ap-t-pausa{display:none}
.ap-batidas{display:flex;gap:5px;flex:1;max-width:260px}
.ap-batidas i{
  flex:1;height:3px;border-radius:2px;background:rgba(130,160,210,.2);
  transition:background .4s var(--curva);
}
.ap-batidas i.on{background:var(--azul)}
.ap-batida-nome{
  font:500 11px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--tx3);
}

@media (max-width:760px){
  .ap-app{grid-template-columns:1fr;min-height:0}
  .ap-lateral{display:none}
  .ap-url b{display:none}
  .ap-term{font-size:11px;padding:8px 12px 12px;height:96px}
  .ap-batida-nome{display:none}
}

/* ═══════════════════════════════════════════════════════════ números */
.ap-numeros{
  display:grid;grid-template-columns:repeat(3,1fr);
  margin:68px auto 0;max-width:760px;
}
.ap-num{padding:8px 16px;text-align:center;position:relative}
.ap-num + .ap-num::before{
  content:"";position:absolute;left:0;top:14%;bottom:14%;width:1px;
  background:linear-gradient(180deg,transparent,rgba(130,160,210,.3),transparent);
}
.ap-num b{
  display:block;font-size:clamp(38px,4.6vw,56px);font-weight:700;
  letter-spacing:-.045em;line-height:1;font-variant-numeric:tabular-nums;
  background:linear-gradient(180deg,#EAF3FF,rgba(154,190,240,.55));
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.ap-num span{display:block;margin-top:9px;font-size:13.5px;color:var(--tx3);
  letter-spacing:-.005em}

/* ══════════════════════════════════════════════════════════ seções */
.ap-secao{padding:130px 0;position:relative}
@media (max-width:760px){.ap-secao{padding:88px 0}}
.ap-rotulo{
  font-size:12.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;
  color:var(--azul);margin-bottom:16px;
}
.ap-h2{
  font-size:clamp(34px,4.8vw,58px);letter-spacing:-.045em;line-height:1.04;
  max-width:22ch;font-weight:700;
}
.ap-h2 .ap-cinza{color:var(--tx3)}
.ap-lead{
  margin-top:20px;max-width:46ch;font-size:clamp(16px,1.4vw,19px);
  color:var(--tx2);line-height:1.5;letter-spacing:-.01em;
}
.ap-lead b{color:var(--tx1);font-weight:560}

/* ════════════════════════════════════════════════ a batida tipográfica
   Uma linha riscada e uma linha nova. Era uma seção de quatro cartões
   com quatro parágrafos; o que ela dizia cabe em dois gestos. */
.ap-golpe{padding:118px 0 112px;text-align:center;overflow:hidden}
@media (max-width:760px){.ap-golpe{padding:84px 0}}
.ap-golpe p{margin-inline:auto;max-width:21ch}
.ap-golpe-de{
  font-size:clamp(30px,4.4vw,52px);font-weight:700;letter-spacing:-.045em;
  line-height:1.16;color:var(--tx3);
}
/* O risco é um GRADIENTE, não um pseudo-elemento: com
   `box-decoration-break:clone` ele se repete em cada linha, e
   `background-size` de 0 a 100% o desenha da esquerda para a direita. Um
   `::after` só atravessaria uma das linhas quando a frase quebra. */
.ap-risco{
  background-image:linear-gradient(to bottom,transparent 51%,var(--erro) 51%,
    var(--erro) calc(51% + 3px),transparent calc(51% + 3px));
  background-repeat:no-repeat;background-size:100% 100%;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
}
.ap-golpe-para{
  margin-top:34px;
  font-size:clamp(30px,4.4vw,52px);font-weight:700;letter-spacing:-.05em;
  line-height:1.08;
  background:linear-gradient(96deg,#fff,#5AA8FF 70%,#9CCFFF);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}

/* ═══════════════════════════════════════════════════ a narrativa
   Quatro etapas à esquerda e um palco preso ao topo à direita. A rolagem
   conduz; os controles tiram a rolagem do volante no primeiro toque. */
.ap-fluxo{display:grid;grid-template-columns:.78fr 1.22fr;gap:64px;
  align-items:start;margin-top:56px}
.ap-palco-fixo{position:sticky;top:92px}
.ap-etapas{display:grid;position:relative;padding-left:28px}
/* O fio de progresso: a barra fria é o caminho, e o preenchimento segue
   o progresso REAL da rolagem na seção (`--prog`, escrito pelo script). */
.ap-etapas::before{
  content:"";position:absolute;left:5px;top:18px;bottom:18px;width:2px;
  border-radius:2px;background:rgba(130,160,210,.2);
}
.ap-etapas::after{
  content:"";position:absolute;left:5px;top:18px;width:2px;
  height:calc(var(--prog,0) * (100% - 36px));border-radius:2px;
  background:linear-gradient(180deg,#5AA8FF,#9CCFFF);
}
.ap-etapa{
  position:relative;padding:30px 0;cursor:pointer;
  border-bottom:1px solid rgba(130,160,210,.14);
}
.ap-etapa:last-child{border-bottom:0}
.ap-etapa::before{
  content:"";position:absolute;left:-28px;top:38px;width:12px;height:12px;
  border-radius:50%;background:#020713;border:2px solid rgba(130,160,210,.35);
  transition:border-color .35s ease-out,transform .35s var(--curva),
             box-shadow .35s var(--curva);
}
.ap-etapa.on::before{
  border-color:var(--azul);transform:scale(1.25);
  box-shadow:0 0 0 5px rgba(31,139,255,.16);
}
.ap-etapa h3{
  font-size:clamp(24px,2.6vw,34px);letter-spacing:-.035em;color:var(--tx3);
  transition:color .35s ease-out;font-weight:700;
}
.ap-etapa p{
  margin-top:8px;font-size:15.5px;color:var(--tx3);line-height:1.5;
  max-width:30ch;transition:color .35s ease-out;
}
.ap-etapa.on h3{color:var(--tx1)}
.ap-etapa.on p{color:var(--tx2)}

.ap-palco{
  position:relative;border-radius:var(--r-xl);background:var(--vidro);
  border:1px solid var(--borda);box-shadow:var(--vidro-sombra);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  backdrop-filter:blur(18px) saturate(140%);
  overflow:hidden;min-height:430px;
}
.ap-palco-topo{
  display:flex;align-items:center;gap:8px;height:42px;padding:0 15px;
  border-bottom:1px solid rgba(130,160,210,.14);background:rgba(2,7,19,.3);
}
.ap-cenas{position:relative}
.ap-cena{padding:20px 20px 24px;font-size:13.5px}
.ap-cena + .ap-cena{border-top:1px solid rgba(130,160,210,.14)}
.ap-cena-tit{
  display:flex;align-items:center;gap:9px;margin-bottom:14px;flex-wrap:wrap;
  font-size:13.5px;font-weight:640;letter-spacing:-.01em;color:var(--tx1);
}

/* os átomos das maquetes — tabela, chips, código, barras, log */
.ap-tab{width:100%;border-collapse:collapse;font-size:13px}
.ap-tab th{
  text-align:left;font-weight:500;font-size:10.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--tx3);padding:0 8px 9px;
  border-bottom:1px solid rgba(130,160,210,.14);
}
.ap-tab td{padding:9px 8px;border-bottom:1px solid rgba(130,160,210,.1);
  color:var(--tx2)}
.ap-tab td:first-child{font-family:var(--mono);color:var(--tx1);font-size:12.5px}
.ap-tab tr:last-child td{border-bottom:0}
.ap-led{display:inline-block;width:7px;height:7px;border-radius:50%;
  background:var(--ok);margin-right:7px;vertical-align:1px}
.ap-led.al{background:var(--alerta)}
.ap-led.cz{background:#2B3B5C}
.ap-etq{
  display:inline-flex;align-items:center;height:22px;padding:0 9px;
  border-radius:7px;font:500 11px/1 var(--mono);color:var(--tx2);
  background:var(--campo);border:1px solid rgba(130,160,210,.2);
}
.ap-chips{display:flex;flex-wrap:wrap;gap:6px}
.ap-chips .ap-etq.mais{color:var(--azul-claro);border-color:var(--azul-borda);
  background:var(--azul-fraco)}
.ap-cod{
  margin:14px 0 0;padding:14px 16px;border-radius:12px;
  background:rgba(1,5,14,.62);color:#DDE7F6;
  font:12.5px/1.75 var(--mono);white-space:pre-wrap;word-break:break-word;
  border:1px solid rgba(130,160,210,.16);
}
.ap-cod .h{color:#8CC8FF}
.ap-cod .v{color:#4ADE80}
.ap-cod .c{color:#8C99B0}
.ap-barras{display:grid;gap:10px}
.ap-barra{display:grid;grid-template-columns:128px 1fr 76px;align-items:center;
  gap:12px;font-size:12.5px}
.ap-barra span:first-child{font-family:var(--mono);color:var(--tx1)}
.ap-barra i{
  display:block;height:8px;border-radius:4px;background:rgba(1,5,14,.6);
  border:1px solid rgba(130,160,210,.16);overflow:hidden;position:relative;
}
.ap-barra i::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:var(--p,100%);
  background:linear-gradient(90deg,#2696FF,#8CC8FF);border-radius:4px;
}
.ap-barra i.al::before{background:linear-gradient(90deg,var(--alerta),#E9A64C)}
.ap-barra em{font-style:normal;color:var(--tx3);text-align:right;
  font-family:var(--mono);font-size:11px}
.ap-log{display:grid;gap:0;font:12.5px/1.7 var(--mono)}
.ap-log div{display:grid;grid-template-columns:50px 1fr;gap:12px;padding:6px 0;
  border-bottom:1px solid rgba(130,160,210,.1);color:var(--tx2)}
.ap-log div:last-child{border-bottom:0}
.ap-log time{color:var(--tx3)}
.ap-log b{color:var(--tx1);font-weight:500}
.ap-log .ok{color:var(--ok)}
.ap-log .al{color:var(--alerta)}

/* os controles do palco. Nascem `hidden` no markup: sem o script as
   quatro cenas ficam empilhadas e "próxima" não teria o que fazer. */
.ap-ctrl{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:16px}
.ap-ctrl[hidden]{display:none}
.ap-ctrl-b,.ap-ctrl-p{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  height:38px;border-radius:var(--r-md);cursor:pointer;
  font:600 13px/1 var(--sans);letter-spacing:-.01em;
  color:var(--tx1);background:var(--campo);
  border:1px solid rgba(130,160,210,.24);
  transition:border-color .25s ease,background-color .25s ease,
             transform .25s var(--curva);
}
.ap-ctrl-b{width:38px;padding:0}
.ap-ctrl-p{padding:0 15px}
.ap-ctrl-b:hover,.ap-ctrl-p:hover{border-color:rgba(140,175,230,.45);
  background-color:rgba(5,14,36,.78);transform:translateY(-1px)}
.ap-ctrl-b svg,.ap-ctrl-p svg{width:13px;height:13px;color:var(--azul)}
.ap-ctrl-p .ap-ic-pausa{display:none}
.ap-ctrl-p[aria-pressed="true"] .ap-ic-play{display:none}
.ap-ctrl-p[aria-pressed="true"] .ap-ic-pausa{display:block}
.ap-pills{display:flex;flex-wrap:wrap;gap:6px;margin-left:4px}
.ap-pill{
  height:32px;padding:0 12px;border-radius:var(--r-md);cursor:pointer;
  font:500 11.5px/1 var(--mono);letter-spacing:.01em;
  color:var(--tx3);background:transparent;
  border:1px solid rgba(130,160,210,.18);
  transition:color .2s ease,background .2s ease,border-color .2s ease;
}
.ap-pill:hover{color:var(--tx1);border-color:rgba(140,175,230,.4)}
.ap-pill[aria-current="true"]{
  color:var(--azul-claro);background:var(--azul-fraco);
  border-color:var(--azul-borda);
}
@media (max-width:960px){
  .ap-fluxo{grid-template-columns:1fr;gap:24px}
  .ap-palco-fixo{position:static;order:-1}
  .anim .ap-palco-fixo{position:sticky;top:60px;z-index:3;padding-bottom:10px}
  .ap-etapas{padding-left:24px}
  .ap-etapa::before{left:-24px;top:34px}
  .ap-etapa{padding:22px 0}
  .ap-etapa h3{font-size:22px}
  .ap-ctrl{margin-top:10px}
  .ap-pills{margin-left:0}
  /* Preso ao topo o palco come metade da tela: a altura mínima do desktop
     deixaria um vazio embaixo da cena mais curta. */
  .ap-palco,.anim .ap-cenas{min-height:340px}
}
@media (max-width:560px){
  .ap-pill{height:30px;padding:0 10px;font-size:11px}
  .ap-cena{padding:14px 14px 18px;font-size:12.5px}
  .ap-barra{grid-template-columns:104px 1fr 62px;gap:8px;font-size:11.5px}
}

/* ═══════════════════════════════════════════════════════ recursos
   Quatro faixas alternadas: de um lado a demonstração, do outro um
   rótulo, um título e UMA frase. A demonstração ocupa mais espaço que o
   texto de propósito — a página mostra o produto, não o descreve. */
.ap-recs{margin-top:16px}
.ap-rec{
  display:grid;grid-template-columns:.8fr 1.3fr;gap:64px;align-items:center;
  padding:74px 0;border-top:1px solid rgba(130,160,210,.14);
}
.ap-rec:first-child{border-top:0;padding-top:44px}
.ap-rec.inv .ap-rec-txt{order:2}
.ap-rec-rot{
  font:600 11.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--azul);margin-bottom:14px;
}
.ap-rec-txt h3{
  font-size:clamp(27px,3.1vw,40px);letter-spacing:-.038em;line-height:1.05;
  font-weight:700;
}
.ap-rec-txt p{margin-top:14px;font-size:16px;color:var(--tx2);line-height:1.5;
  max-width:32ch}
@media (max-width:940px){
  .ap-rec{grid-template-columns:1fr;gap:30px;padding:54px 0}
  .ap-rec.inv .ap-rec-txt{order:0}
}

/* A moldura das demonstrações: o mesmo vidro da janela, menor. O brilho
   segue o ponteiro (`--mx/--my`, escritos pelo script). */
.ap-vis{
  position:relative;border-radius:var(--r-xl);overflow:hidden;
  background:var(--vidro);border:1px solid var(--borda);
  box-shadow:var(--vidro-sombra);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  backdrop-filter:blur(18px) saturate(140%);
  transition:border-color .4s ease-out,transform .5s var(--curva);
}
.ap-vis:hover{border-color:rgba(120,180,255,.5);transform:translateY(-3px)}
/* O brilho tem de ser `::before`: a varredura de
   `test_a_pagina_aparece_inteira_sem_javascript` só perdoa `opacity:0`
   em `.anim …`, em `@keyframes` e em `::before`. */
.ap-vis::before{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;opacity:0;
  background:radial-gradient(240px circle at var(--mx,50%) var(--my,0),
             rgba(140,200,255,.12),transparent 70%);
  transition:opacity .4s ease-out;
}
.ap-vis:hover::before{opacity:1}
.ap-vis-topo{
  display:flex;align-items:center;gap:10px;height:40px;padding:0 15px;
  border-bottom:1px solid rgba(130,160,210,.14);background:rgba(2,7,19,.3);
  font:600 10.5px/1 var(--mono);letter-spacing:.09em;text-transform:uppercase;
  color:var(--tx3);
}
/* Marca o que é maquete. A página não finge ser captura de tela. */
.ap-vis-demo{
  margin-left:auto;padding:4px 8px;border-radius:6px;letter-spacing:.06em;
  color:var(--tx3);background:var(--campo);
  border:1px solid rgba(130,160,210,.2);text-transform:none;font-weight:500;
}
.ap-vis-corpo{padding:16px 16px 18px;display:grid;gap:12px;position:relative}

/* recurso 1 · execução em massa: cinco equipamentos atravessando os
   quatro estados de um passo (pendente, executando, concluído, falhou) */
.ap-exec{display:grid;gap:9px}
.ap-eq{display:grid;grid-template-columns:120px 1fr 92px;align-items:center;
  gap:12px;font-size:12px}
.ap-eq > span{font-family:var(--mono);color:var(--tx1)}
.ap-eq .tr{
  position:relative;height:7px;border-radius:4px;background:rgba(1,5,14,.6);
  border:1px solid rgba(130,160,210,.16);overflow:hidden;
}
.ap-eq .tr::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:100%;
  border-radius:4px;background:linear-gradient(90deg,#2696FF,#8CC8FF);
}
.ap-eq.falha .tr::before{width:66%;
  background:linear-gradient(90deg,var(--alerta),#E9A64C)}
.ap-fase{position:relative;height:16px}
.ap-fase b{
  display:none;position:absolute;right:0;top:0;white-space:nowrap;
  font:500 11px/16px var(--mono);color:var(--tx3);
}
.ap-fase b:last-child{display:block}
.ap-fase b.ok{color:var(--ok)}
.ap-fase b.al{color:var(--alerta)}

/* recurso 2 · backup: a versão selecionada muda e a diferença se refaz */
.ap-versoes{display:grid;font:12px/1.6 var(--mono)}
.ap-versoes div{
  display:grid;grid-template-columns:86px 1fr auto;gap:12px;align-items:center;
  padding:7px 10px;border-radius:9px;color:var(--tx2);
  border:1px solid transparent;
}
.ap-versoes div:last-child{background:var(--azul-fraco);
  border-color:var(--azul-borda);color:var(--tx1)}
.ap-versoes time{color:var(--tx3)}
.ap-versoes em{font-style:normal;font-size:10.5px;color:var(--tx3)}
.ap-diff{
  margin:0;padding:13px 15px;border-radius:12px;background:rgba(1,5,14,.62);
  border:1px solid rgba(130,160,210,.16);
  font:12px/1.85 var(--mono);white-space:pre-wrap;word-break:break-word;
  color:var(--tx2);overflow:hidden;
}
.ap-diff span{display:block}
.ap-diff .c{color:var(--tx3)}
.ap-diff .m{color:var(--erro)}
.ap-diff .p{color:var(--ok)}

/* recurso 3 · automação: gatilho → comando → resultado → notificação */
.ap-elos{display:grid;gap:0;padding:4px 0}
.ap-elo{
  display:grid;grid-template-columns:28px 1fr auto;align-items:center;gap:12px;
  padding:11px 12px;border-radius:11px;
  border:1px solid rgba(130,160,210,.16);background:rgba(10,24,54,.4);
  transition:border-color .45s ease-out,background .45s ease-out;
}
.ap-elo i{
  width:28px;height:28px;border-radius:9px;display:grid;place-items:center;
  color:var(--tx3);background:var(--campo);
  border:1px solid rgba(130,160,210,.2);
  transition:color .45s ease-out,background .45s ease-out,
             border-color .45s ease-out,box-shadow .45s var(--curva);
}
.ap-elo i svg{width:14px;height:14px}
.ap-elo b{font-size:13px;font-weight:600;color:var(--tx1);letter-spacing:-.01em}
.ap-elo b small{display:block;font-weight:400;font-size:11px;color:var(--tx3);
  margin-top:2px;font-family:var(--mono)}
.ap-elo em{font-style:normal;font:500 10.5px/1 var(--mono);color:var(--tx3)}
.ap-elo-fio{
  height:16px;margin-left:25px;width:2px;border-radius:2px;
  background:rgba(130,160,210,.2);position:relative;overflow:hidden;
}
.ap-elo-fio::before{
  content:"";position:absolute;left:0;right:0;top:-100%;height:100%;
  background:linear-gradient(180deg,transparent,var(--azul),transparent);
}

/* recurso 4 · monitoria: estado mudando, traçado se desenhando, alarme */
.ap-kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.ap-kpis div{
  padding:12px 13px;border-radius:11px;background:rgba(10,24,54,.4);
  border:1px solid rgba(130,160,210,.16);
}
.ap-kpis b{display:block;font-size:24px;font-weight:700;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums}
.ap-kpis b.al{color:var(--alerta)}
.ap-kpis span{display:block;margin-top:3px;font-size:11px;color:var(--tx3)}
.ap-spark{
  width:100%;height:66px;display:block;border-radius:11px;
  background:rgba(10,24,54,.4);border:1px solid rgba(130,160,210,.16);
}
.ap-spark polyline{stroke:#5AA8FF;stroke-width:2;fill:none;
  stroke-linejoin:round;stroke-linecap:round}
.ap-spark .area{fill:rgba(31,139,255,.16);stroke:none}
.ap-alarmes{display:grid;gap:2px;font-size:12.5px}
.ap-alarmes div{
  display:grid;grid-template-columns:auto auto 1fr auto;gap:9px;align-items:center;
  padding:9px 10px;border-radius:9px;color:var(--tx2);
  background:rgba(10,24,54,.34);
}
.ap-alarmes b{font:500 12px/1 var(--mono);color:var(--tx1)}
.ap-alarmes time{font:500 11px/1 var(--mono);color:var(--tx3)}
@media (max-width:420px){.ap-alarmes time{display:none}}

/* o resto do produto: só o nome. O que não é o trabalho do dia a dia
   não precisa de um cartão com parágrafo — precisa de estar listado. */
.ap-mais-cab{margin-top:62px;margin-bottom:0;text-align:center}
.ap-mais{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px;
  justify-content:center}
.ap-mais span{
  display:inline-flex;align-items:center;gap:9px;height:40px;padding:0 16px;
  border-radius:var(--r-md);font-size:13.5px;font-weight:540;
  color:var(--tx2);background:var(--campo);
  border:1px solid rgba(130,160,210,.2);
  transition:color .25s ease,border-color .25s ease,
             transform .25s var(--curva);
}
.ap-mais span svg{width:15px;height:15px;color:var(--azul);opacity:.9}
.ap-mais span:hover{color:var(--tx1);border-color:var(--azul-borda);
  transform:translateY(-2px)}

/* ═════════════════════════════════════════════════════ arquitetura
   Nuvem, coletor e equipamentos. Os pulsos mostram a direção real das
   conexões: a de saída nasce no coletor e vai para a nuvem; o plano
   desce por ela; dentro da rede do cliente o comando vai ao equipamento
   e a resposta volta. Cada nó é um botão, alinhado à coluna do desenho
   que está logo acima dele. */
.ap-arq{
  margin-top:48px;border-radius:var(--r-xl);overflow:hidden;
  background:var(--vidro);border:1px solid var(--borda);
  box-shadow:var(--vidro-sombra);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  backdrop-filter:blur(18px) saturate(140%);
}
.ap-diagrama{width:100%;height:auto;display:block;font-family:var(--mono)}
.ap-diagrama .cx{
  fill:rgba(10,24,54,.5);stroke:rgba(130,160,210,.26);
  transition:fill .35s ease-out,stroke .35s ease-out;
}
.ap-diagrama .d-nuvem .cx{stroke:rgba(90,168,255,.3)}
.ap-diagrama .d-coletor .cx{stroke:rgba(74,222,128,.32)}
.ap-diagrama .d-rede .cx{stroke:rgba(183,156,255,.32)}
.ap-diagrama .tit{
  fill:#F2F6FC;font-size:15px;font-weight:650;letter-spacing:-.01em;
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
}
.ap-diagrama .sub{fill:#8C99B0;font-size:9px;letter-spacing:.08em}
.ap-diagrama .ico{color:#8C99B0;transition:color .35s ease-out}
.ap-diagrama .d-nuvem .ico{color:#5AA8FF}
.ap-diagrama .d-coletor .ico{color:#4ADE80}
.ap-diagrama .trilho{stroke:rgba(130,160,210,.26);stroke-width:1.4;fill:none}
.ap-diagrama .pulso{
  stroke-width:3.4;fill:none;stroke-linecap:round;stroke-dasharray:36 400;
}
.ap-diagrama .pulso.sobe{stroke:#4ADE80}
.ap-diagrama .pulso.desce{stroke:#5AA8FF}
.ap-diagrama .pulso.rede{stroke:#B79CFF}
/* O rastro: o mesmo traço, mais largo e quase transparente, sob o pulso.
   É o que dá o brilho sem um filtro — e filtro animado é o que fazia o
   fundo piscar. */
.ap-diagrama .rastro{stroke-width:9;opacity:.16}
.ap-diagrama .selo{fill:#8C99B0;font-size:9.5px;letter-spacing:.1em}
.ap-diagrama .eqp{fill:rgba(183,156,255,.16);stroke:rgba(183,156,255,.36)}
.ap-diagrama .eqd{fill:#B79CFF}
.ap-diagrama .cadeado{fill:#06122B;stroke:rgba(90,168,255,.55)}
.ap-nos{display:grid;grid-template-columns:repeat(3,1fr);
  border-top:1px solid rgba(130,160,210,.16)}
.ap-nob{
  position:relative;
  -webkit-appearance:none;appearance:none;cursor:pointer;text-align:left;
  padding:20px 22px 22px;border:0;background:transparent;
  font:inherit;color:var(--tx3);
  transition:background .3s ease-out,color .3s ease-out;
}
.ap-nob + .ap-nob{border-left:1px solid rgba(130,160,210,.16)}
.ap-nob:hover{background:rgba(120,160,230,.06);color:var(--tx2)}
.ap-nob b{
  display:flex;align-items:center;gap:9px;font-size:14.5px;font-weight:650;
  letter-spacing:-.015em;color:var(--tx2);transition:color .3s ease-out;
}
.ap-nob b svg{width:16px;height:16px}
.ap-nob span{display:block;margin-top:8px;font-size:13px;line-height:1.5}
.ap-nob[aria-pressed="true"]{background:rgba(31,139,255,.1);color:var(--tx2)}
.ap-nob[aria-pressed="true"] b{color:var(--tx1)}
.ap-nob[aria-pressed="true"] b svg{color:var(--azul-claro)}

/* No celular o desenho de 1120 de largura cabe em 350 px: o rótulo de
   15 px chega a 5 px na tela, e é ilegível. O diagrama então vira a
   própria lista de nós, empilhada, com o fio e o pulso descendo por ela
   — a mesma história, no formato que a tela tem. */
@media (max-width:760px){
  .ap-diagrama{display:none}
  .ap-nos{grid-template-columns:1fr;border-top:0;padding:6px 0}
  .ap-nob{padding:16px 18px 18px 56px}
  .ap-nob + .ap-nob{border-left:0;border-top:1px solid rgba(130,160,210,.14)}
  .ap-nob::before{
    content:"";position:absolute;left:28px;top:0;bottom:0;width:2px;
    background:rgba(130,160,210,.22);
  }
  .ap-nob:first-child::before{top:28px}
  .ap-nob:last-child::before{bottom:calc(100% - 28px)}
  .ap-nob::after{
    content:"";position:absolute;left:23px;top:21px;width:12px;height:12px;
    border-radius:50%;background:#020713;
    box-shadow:0 0 0 2px var(--azul-borda);
  }
  .ap-nob[aria-pressed="true"]::after{
    box-shadow:0 0 0 2px var(--azul),0 0 0 6px rgba(31,139,255,.18);
  }
  .anim .ap-nob::before{
    background:linear-gradient(180deg,rgba(130,160,210,.22) 0 42%,
      var(--azul) 50%,rgba(130,160,210,.22) 58% 100%);
    background-size:100% 320%;
    animation:ap-fio-desce 2.6s linear infinite;
  }
}
@keyframes ap-fio-desce{
  from{background-position:0 -110%}to{background-position:0 210%}
}

/* ════════════════════════════════════════ segurança + compatibilidade
   Uma seção só, em duas colunas: à esquerda os controles que existem no
   código, à direita a cobertura real do catálogo. */
.ap-dupla{display:grid;grid-template-columns:1.05fr .95fr;gap:72px;
  align-items:start;margin-top:48px}
.ap-dupla .ap-h2{font-size:clamp(28px,3.2vw,42px);max-width:14ch}
@media (max-width:980px){.ap-dupla{grid-template-columns:1fr;gap:56px}}
.ap-guardas{display:grid;gap:0;margin-top:30px}
.ap-guarda{
  display:grid;grid-template-columns:32px 1fr;gap:14px;align-items:start;
  padding:15px 0;border-bottom:1px solid rgba(130,160,210,.12);
}
.ap-guarda:last-child{border-bottom:0}
.ap-guarda-ico{
  width:32px;height:32px;border-radius:10px;display:grid;place-items:center;
  color:var(--azul-claro);background:var(--azul-fraco);
  border:1px solid var(--azul-borda);
  transition:transform .3s var(--curva),box-shadow .3s var(--curva);
}
.ap-guarda-ico svg{width:15px;height:15px}
.ap-guarda:hover .ap-guarda-ico{transform:scale(1.08);
  box-shadow:0 0 0 4px rgba(31,139,255,.1)}
.ap-guarda h3{font-size:15px;letter-spacing:-.018em;font-weight:620;
  line-height:1.3}
.ap-guarda p{margin-top:3px;font-size:13.5px;color:var(--tx3);line-height:1.5}

.ap-cobertura{display:grid;gap:10px;margin-top:30px}
.ap-cob{
  display:grid;grid-template-columns:auto 1fr;gap:16px;align-items:baseline;
  padding:16px 20px;border-radius:var(--r-lg);
  background:rgba(10,24,54,.4);border:1px solid rgba(130,160,210,.18);
}
.ap-cob b{
  font:700 30px/1 var(--sans);letter-spacing:-.04em;color:var(--tx1);
  font-variant-numeric:tabular-nums;
}
.ap-cob span{font-size:13.5px;color:var(--tx3);line-height:1.45}
.ap-vendores{display:flex;flex-wrap:wrap;gap:6px;margin-top:18px}
.ap-vendor{
  display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 13px;
  border-radius:var(--r-md);font:500 12.5px/1 var(--sans);color:var(--tx2);
  background:var(--campo);border:1px solid rgba(130,160,210,.2);
  transition:border-color .25s ease,color .25s ease;
}
.ap-vendor:hover{border-color:var(--azul-borda);color:var(--tx1)}
.ap-vendor em{font-style:normal;font:500 10.5px/1 var(--mono);color:var(--tx3)}
.ap-abrir{margin-top:18px;font-size:13.5px;color:var(--tx3)}
.ap-abrir > summary{
  cursor:pointer;list-style:none;display:inline-flex;align-items:center;gap:8px;
  color:var(--azul);font-weight:560;text-decoration:underline;
  text-underline-offset:3px;text-decoration-color:rgba(74,168,255,.5);
}
.ap-abrir > summary::-webkit-details-marker{display:none}
.ap-abrir > summary:hover{color:#8CC8FF}
.ap-abrir > summary svg{width:12px;height:12px;transition:transform .25s var(--curva)}
.ap-abrir[open] > summary svg{transform:rotate(180deg)}
.ap-abrir-cx{
  margin-top:16px;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(176px,1fr));gap:14px 20px;
}
.ap-abrir-cx h4{margin:0 0 7px;font-size:12px;font-weight:620;color:var(--tx2);
  letter-spacing:-.01em}
.ap-abrir-cx ul{margin:0;padding:0;list-style:none;display:grid;gap:4px}
.ap-abrir-cx li{font:500 11.5px/1.45 var(--mono);color:var(--tx3)}
.ap-abrir-cx li sup{color:var(--alerta);font-size:10px;margin-left:2px}
.ap-nota{margin-top:18px;font-size:13px;color:var(--tx3);line-height:1.6}
.ap-nota b{color:var(--tx2);font-weight:600}

/* ════════════════════════════════════════════════════════════ fecho */
.ap-fecho{position:relative;padding:150px 0 130px;text-align:center}
.ap-fecho .ap-h2{margin-inline:auto;max-width:19ch}
.ap-fecho .ap-lead{margin-inline:auto;text-align:center;max-width:40ch}
.ap-fecho .ap-acoes{justify-content:center}
.ap-fecho .ap-fino{margin-top:24px;font-size:13px;color:var(--tx3)}

.ap-rodape{
  border-top:1px solid rgba(130,160,210,.14);padding:32px 0 44px;
  color:var(--tx3);font-size:13px;
}
.ap-rodape-in{display:flex;flex-wrap:wrap;gap:18px;align-items:center}
.ap-rodape .ap-espaco{flex:1}
.ap-rodape a{color:var(--tx2)}
.ap-rodape a:hover{color:var(--tx1)}
.ap-rodape nav{display:flex;gap:18px;flex-wrap:wrap}
.ap-rodape-marca{display:flex;align-items:center;gap:10px;color:var(--tx2)}
.ap-rodape-marca .ap-logo{width:24px;height:24px;border-radius:7px}
.ap-rodape-marca .ap-logo svg{width:14px;height:14px}
@media (max-width:640px){
  .ap-rodape-in{flex-direction:column;align-items:flex-start;gap:14px}
  .ap-rodape .ap-espaco{display:none}
}

/* ════════════════════════════════════════════════════════ movimento
   TUDO o que segue só existe quando o script decidiu animar (`.anim` no
   <html>). Sem JavaScript, ou com "reduzir movimento" ligado no sistema,
   nada aqui vale — e a página aparece inteira, de uma vez, com cada
   demonstração no seu estado final.

   As demonstrações em laço ficam PARADAS fora da tela: o script põe
   `.ao-vivo` no quadro quando ele entra na viewport e tira quando sai. */
.anim [data-rv]{
  opacity:0;transform:translateY(26px);
  transition:opacity .9s var(--curva),transform .9s var(--curva);
  transition-delay:var(--atraso,0ms);
}
.anim [data-rv].vis{opacity:1;transform:none}
.anim .ap-h1[data-rv]{transform:translateY(34px) scale(.98)}
.anim .ap-tela{
  opacity:0;transform:translateY(54px) rotateX(10deg);
  transition:opacity 1.2s var(--curva) .1s,transform 1.4s var(--curva) .1s;
}
.anim .ap-tela.vis{opacity:1;transform:none}
.anim [data-laco] *{animation-play-state:paused}
.anim [data-laco].ao-vivo *{animation-play-state:running}

/* --- o fundo do login: as curvas se desenham uma vez, as luzes derivam
   devagar, e os cometas passam de vez em quando. Nenhum desfoque é
   animado — é o que separa este fundo do que piscava. */
.anim .fl-luz-a{animation:fl-luz-a 28s ease-in-out infinite alternate}
.anim .fl-luz-b{animation:fl-luz-b 36s ease-in-out infinite alternate}
.anim .fl-c1{animation:fl-deriva-a 40s ease-in-out infinite alternate}
.anim .fl-c2{animation:fl-deriva-b 54s ease-in-out infinite alternate}
.anim .fl-traco{stroke-dasharray:1000;
  animation:fl-desenha 2.4s var(--curva) .15s both}
.anim .fl-cometa{display:block;opacity:0;animation:fl-cometa 15s 3s infinite}
.anim .fl-c2 .fl-cometa{animation-duration:18s;animation-delay:7s}
.anim .fl-c2 .fl-cometa + .fl-cometa{animation-duration:23s;animation-delay:12s}
@keyframes fl-desenha{from{stroke-dashoffset:1000}}
@keyframes fl-luz-a{from{opacity:.75;transform:translate3d(0,0,0)}
  to{opacity:1;transform:translate3d(7vmax,5vmax,0)}}
@keyframes fl-luz-b{from{opacity:1;transform:translate3d(0,0,0)}
  to{opacity:.7;transform:translate3d(-6vmax,-4vmax,0)}}
@keyframes fl-deriva-a{from{opacity:.85;transform:translate3d(0,0,0) rotate(0) scale(1)}
  to{opacity:1;transform:translate3d(-1.2%,1%,0) rotate(-1deg) scale(1.03)}}
@keyframes fl-deriva-b{from{opacity:1;transform:translate3d(0,0,0) rotate(0) scale(1)}
  to{opacity:.85;transform:translate3d(1%,-1.4%,0) rotate(1.2deg) scale(1.04)}}
/* As paradas transparentes vão todas no PRIMEIRO bloco: a varredura de
   `test_a_pagina_aparece_inteira_sem_javascript` corta a folha em `}` e
   trata cada porcentagem como seletor. Blocos de keyframe não têm ordem
   em CSS, e declarações do mesmo stop se somam. */
@keyframes fl-cometa{
  0%,36%,100%{opacity:0}
  0%{stroke-dashoffset:60;animation-timing-function:cubic-bezier(.45,0,.55,1)}
  4%,30%{opacity:1}
  36%,100%{stroke-dashoffset:-1000}}

/* --- o palco da narrativa: uma cena de cada vez, e as linhas entram
   escalonadas. Sem `.anim` as quatro cenas ficam empilhadas e visíveis. */
.anim .ap-cenas{min-height:430px}
.anim .ap-cena{
  position:absolute;inset:0;opacity:0;transform:translateY(14px) scale(.985);
  transition:opacity .5s var(--curva),transform .6s var(--curva);
  pointer-events:none;border-top:0;
}
.anim .ap-cena.on{opacity:1;transform:none;pointer-events:auto}
.anim .ap-cena.on .ap-tab tbody tr,
.anim .ap-cena.on .ap-barra,
.anim .ap-cena.on .ap-log div,
.anim .ap-cena.on .ap-chips .ap-etq{animation:ap-linha .5s var(--curva) both}
@keyframes ap-linha{from{opacity:0;transform:translateY(9px)}}
.anim .ap-cena.on .ap-tab tbody tr:nth-child(2),
.anim .ap-cena.on .ap-barra:nth-child(2),
.anim .ap-cena.on .ap-log div:nth-child(2),
.anim .ap-cena.on .ap-chips .ap-etq:nth-child(2){animation-delay:.07s}
.anim .ap-cena.on .ap-tab tbody tr:nth-child(3),
.anim .ap-cena.on .ap-barra:nth-child(3),
.anim .ap-cena.on .ap-log div:nth-child(3),
.anim .ap-cena.on .ap-chips .ap-etq:nth-child(3){animation-delay:.14s}
.anim .ap-cena.on .ap-tab tbody tr:nth-child(4),
.anim .ap-cena.on .ap-barra:nth-child(4),
.anim .ap-cena.on .ap-log div:nth-child(4),
.anim .ap-cena.on .ap-chips .ap-etq:nth-child(4){animation-delay:.21s}
.anim .ap-cena.on .ap-tab tbody tr:nth-child(5),
.anim .ap-cena.on .ap-barra:nth-child(5){animation-delay:.28s}
.anim .ap-cena.on .ap-cod{animation:ap-linha .6s var(--curva) .18s both}
.anim .ap-cena .ap-barra i::before{width:0}
.anim .ap-cena.on .ap-barra i::before{
  width:var(--p,100%);transition:width 1.1s var(--curva) .3s;
}

/* --- a batida tipográfica: o risco atravessa linha por linha.
   `nth-of-type` e não `nth-child`: o <br> entre as duas frases também é
   um filho, e faria a segunda virar a terceira. */
.anim .ap-risco{background-size:0 100%;
  transition:background-size .6s var(--curva)}
.anim .vis span.ap-risco:nth-of-type(1){background-size:100% 100%;
  transition-delay:.3s}
.anim .vis span.ap-risco:nth-of-type(2){background-size:100% 100%;
  transition-delay:.58s}
.anim .ap-golpe-para{
  opacity:0;transform:translateY(20px) scale(.97);
  transition:opacity .7s var(--curva) .5s,transform .8s var(--curva) .5s;
}
.anim .ap-golpe-para.vis{opacity:1;transform:none}

/* --- o hero: sete batidas */
.anim .ap-malha .no{
  opacity:0;transform:translateX(16px);
  transition:opacity .45s var(--curva),transform .5s var(--curva);
  transition-delay:calc(var(--i,0) * 55ms);
}
.anim .ap-op.b1 .no{opacity:1;transform:none}
.anim .ap-op.b2 .anel{display:block;animation:ap-anel .5s var(--curva) both;
  animation-delay:calc(var(--i,0) * 45ms)}
@keyframes ap-anel{from{opacity:0;transform:scale(.8)}to{opacity:.75}}
.anim .ap-malha .plano{opacity:0;transform:translateY(8px);
  transition:opacity .45s var(--curva),transform .5s var(--curva)}
.anim .ap-op.b3 .plano{opacity:1;transform:none}
.anim .ap-malha .fio{opacity:.14;transition:opacity .5s ease-out}
.anim .ap-op.b4 .fio{opacity:.5}
.anim .ap-op.b4 .halo{display:block;animation:ap-halo 1.6s ease-out infinite}
@keyframes ap-halo{0%,100%{opacity:0;transform:scale(.9)}35%{opacity:.5;transform:scale(1.25)}}
/* O tracinho de luz: `dasharray: 22 560` deixa um traço de 22 e um vão
   de 560 (período 582). Com `dashoffset` em 582 o traço do segundo
   período cai exatamente no início do fio; descendo até 368 ele
   atravessa os ~190 do fio mais longo e sai pela ponta. Ir até 0
   recomeçaria o padrão e o traço piscaria de volta no início. */
.anim .ap-op.b5 .faisca{
  display:block;stroke-dashoffset:582;
  animation:ap-faisca 1.5s linear infinite;
  animation-delay:calc(var(--i,0) * 110ms);
}
@keyframes ap-faisca{from{stroke-dashoffset:582}to{stroke-dashoffset:368}}
.anim .ap-op.b6 .faisca{animation-direction:reverse;animation-duration:1.2s}
.anim .ap-malha .st{opacity:0;transition:opacity .4s ease-out;
  transition-delay:calc(var(--i,0) * 130ms)}
.anim .ap-op.b6 .st{opacity:1}
.anim .ap-malha .no .pt{transition:fill .4s ease-out;
  transition-delay:calc(var(--i,0) * 130ms)}
.anim .ap-op .no.ok .pt,.anim .ap-op .no.al .pt{fill:#2B3B5C}
.anim .ap-op.b6 .no.ok .pt{fill:#4ADE80}
.anim .ap-op.b6 .no.al .pt{fill:#F2B457}

/* --- recurso 1: os quatro estados de um passo, em laço de 7,2 s */
.anim .ap-eq .tr::before{animation:ap-andar 7.2s var(--curva) infinite;
  animation-delay:calc(var(--i,0) * .5s)}
@keyframes ap-andar{
  0%,8%{width:0}
  26%{width:42%}
  44%,100%{width:100%}
}
.anim .ap-eq.falha .tr::before{animation-name:ap-andar-falha}
@keyframes ap-andar-falha{
  0%,8%{width:0}
  26%{width:38%}
  44%,100%{width:66%}
}
.anim .ap-fase b{
  display:block;opacity:0;animation:ap-fase 7.2s linear infinite;
  animation-delay:calc(var(--i,0) * .5s);
}
@keyframes ap-fase{0%,100%{opacity:0}}
.anim .ap-fase b:nth-child(1){animation-name:ap-fase-1}
.anim .ap-fase b:nth-child(2){animation-name:ap-fase-2}
.anim .ap-fase b:nth-child(3){animation-name:ap-fase-3}
@keyframes ap-fase-1{9%,100%{opacity:0}0%,7%{opacity:1}}
@keyframes ap-fase-2{0%,8%,44%,100%{opacity:0}10%,40%{opacity:1}}
@keyframes ap-fase-3{0%,42%{opacity:0}46%,100%{opacity:1}}

/* --- recurso 2: a versão selecionada troca e a diferença se refaz */
.anim .ap-versoes div{animation:ap-ver 8s var(--curva) infinite}
.anim .ap-versoes div:nth-child(2){animation-name:ap-ver-2}
@keyframes ap-ver{
  0%,44%{background:var(--azul-fraco);border-color:var(--azul-borda);color:#F2F6FC}
  52%,100%{background:transparent;border-color:transparent;color:#B6C2D6}
}
@keyframes ap-ver-2{
  0%,44%{background:transparent;border-color:transparent;color:#B6C2D6}
  52%,100%{background:var(--azul-fraco);border-color:var(--azul-borda);color:#F2F6FC}
}
.anim .ap-diff .m{animation:ap-sai 8s var(--curva) infinite;
  animation-delay:calc(var(--i,0) * .12s)}
@keyframes ap-sai{
  0%,6%{opacity:0;transform:translateX(-14px)}
  16%,46%{opacity:1;transform:none}
  56%,100%{opacity:.3;transform:translateX(-10px)}
}
.anim .ap-diff .p{animation:ap-entra 8s var(--curva) infinite;
  animation-delay:calc(var(--i,0) * .12s)}
@keyframes ap-entra{
  0%,10%{opacity:0;transform:translateX(16px)}
  22%,46%{opacity:1;transform:none}
  56%,100%{opacity:1;transform:none;background:rgba(74,222,128,.1)}
}

/* --- recurso 3: a cadeia da automação acendendo elo por elo */
.anim .ap-elo{animation:ap-elo 7s var(--curva) infinite;
  animation-delay:calc(var(--i,0) * 1.1s)}
@keyframes ap-elo{
  0%,4%{border-color:rgba(130,160,210,.16);background:rgba(10,24,54,.4)}
  12%,62%{border-color:var(--azul-borda);background:rgba(31,139,255,.12)}
  74%,100%{border-color:rgba(130,160,210,.16);background:rgba(10,24,54,.4)}
}
.anim .ap-elo i{animation:ap-elo-ico 7s var(--curva) infinite;
  animation-delay:calc(var(--i,0) * 1.1s)}
@keyframes ap-elo-ico{
  0%,4%{color:#8C99B0;background:rgba(4,11,28,.62);box-shadow:none}
  12%,62%{color:#8CC8FF;background:rgba(31,139,255,.14);
    box-shadow:0 0 0 4px rgba(31,139,255,.12)}
  74%,100%{color:#8C99B0;background:rgba(4,11,28,.62);box-shadow:none}
}
.anim .ap-elo-fio::before{animation:ap-descer 7s linear infinite;
  animation-delay:calc(var(--i,0) * 1.1s + .5s)}
@keyframes ap-descer{0%,6%{top:-100%}18%,100%{top:100%}}

/* --- recurso 4: o traçado se desenha, o estado muda, o alarme resolve */
.anim .ap-spark polyline{
  stroke-dasharray:360;stroke-dashoffset:360;
  animation:ap-tracar 9s var(--curva) infinite;
}
@keyframes ap-tracar{0%{stroke-dashoffset:360}40%,100%{stroke-dashoffset:0}}
.anim .ap-spark .area{opacity:0;animation:ap-area 9s var(--curva) infinite}
@keyframes ap-area{0%,24%{opacity:0}44%,100%{opacity:1}}
.anim .ap-alarmes div{animation:ap-alarme 9s var(--curva) infinite;
  animation-delay:calc(var(--i,0) * .9s)}
@keyframes ap-alarme{
  0%,30%{opacity:0;transform:translateY(10px)}
  42%,100%{opacity:1;transform:none}
}
.anim .ap-alarmes .ap-led.muda{animation:ap-muda 9s step-end infinite}
@keyframes ap-muda{0%,54%{background:#F2B457}56%,100%{background:#4ADE80}}
.anim .ap-kpis b.al{animation:ap-aviso 9s ease-in-out infinite}
@keyframes ap-aviso{0%,48%{opacity:1}52%{opacity:.35}58%,100%{opacity:1}}

/* --- arquitetura: os pulsos atravessam os trilhos.
   `dasharray: 36 400` dá período 436; com `dashoffset` de 436 a 235 o
   traço entra no início do trilho e sai pela ponta dos 165. */
.anim .ap-diagrama .pulso{
  stroke-dashoffset:436;animation:ap-pulsar 2s linear infinite;
  animation-delay:calc(var(--i,0) * 320ms);
}
@keyframes ap-pulsar{from{stroke-dashoffset:436}to{stroke-dashoffset:235}}
.anim .ap-diagrama .pulso.sobe{animation-duration:2.6s}
.anim .ap-diagrama .eqd{animation:ap-respira 3.4s ease-in-out infinite;
  animation-delay:calc(var(--i,0) * 240ms)}
@keyframes ap-respira{0%,100%{opacity:.3}50%{opacity:1}}
/* O nó escolhido ganha a luz; os outros recuam. */
.ap-arq[data-no="nuvem"] .d-nuvem .cx,
.ap-arq[data-no="coletor"] .d-coletor .cx,
.ap-arq[data-no="rede"] .d-rede .cx{
  fill:rgba(31,139,255,.14);stroke:rgba(90,168,255,.6);
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .ap-ponto,.ap-cursor,.ap-brilho,.ap-chip.vivo::before,
  .fl-luz,.fl-camada,.fl-cometa{animation:none}
  .ap-janela{transform:none}
  *{animation-duration:.01ms !important;transition-duration:.01ms !important}
}
