/* ── blindagem: a vitrine não herda estilo de nada em volta ────── */
.vcss-root, .vcss-root *, .vcss-root *::before, .vcss-root *::after{
  background:none;border:0;border-radius:0;box-shadow:none;outline:0;
  margin:0;padding:0;float:none;vertical-align:baseline;max-width:none;min-height:0;
  color:inherit;font-family:inherit;font-size:inherit;font-weight:inherit;font-style:normal;
  line-height:inherit;letter-spacing:normal;word-spacing:normal;
  text-align:inherit;text-transform:none;text-decoration:none;text-shadow:none;text-indent:0;
  list-style:none;
}
.vcss-root{isolation:isolate;overflow-x:hidden;text-align:left}
.vcss-root img,.vcss-root svg,.vcss-root canvas{max-width:100%}
.vcss-root b,.vcss-root strong{font-weight:500}

/* ══════════════════════════════════════════════════════════════════
   LAYOUT DA VITRINE — sistema Factory
   Sala de controle: canvas preto, Geist em peso 400 com tracking
   negativo, e cor cromática só para estado. A profundidade vem do
   contraste e do espaçamento, nunca de sombra ou brilho.
   ══════════════════════════════════════════════════════════════════ */

.vcss-root{
  /* neutros */
  --canvas:#0C2340;      /* fundo de tudo                          */
  --lift:#173052;        /* superfície um passo acima do fundo     */
  --stroke:#2B4A72;      /* hairline de borda                      */
  --graphite:#3E5D85;    /* preenchimento neutro de dado           */
  --granite:#9DB0C8;     /* texto secundário                       */
  --stone:#b8b3b0;       /* texto terciário, sobrancelhas          */
  --bone:#eeeeee;        /* texto primário e cartão claro          */
  --chalk:#fafafa;       /* preenchimento claro de ênfase          */
  /* acentos funcionais: só estado, nunca decoração */
  --signal:#FF5A1F;
  --metric:#D6F35B;

  --sans:'Geist',Inter,system-ui,-apple-system,sans-serif;
  --mono:'Geist Mono','JetBrains Mono',ui-monospace,monospace;

  /* apelidos que a metade das animações ainda usa */
  --bg:var(--canvas); --card:var(--lift); --card2:var(--lift);
  --border:var(--stroke); --fg:var(--bone);
  --fg-muted:var(--granite); --fg-dim:var(--stone);
  --accent:var(--signal); --display:var(--sans); --ui:var(--sans);
}
.vcss-root *, .vcss-root *::before, .vcss-root *::after{box-sizing:border-box}
.vcss-root{
  margin:0;background:var(--canvas);color:var(--bone);
  font-family:var(--sans);font-size:16px;line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
.vcss-root p{margin:0}
.vcss-root .wrap{max-width:1200px;margin:0 auto;padding:0 24px}
.vcss-root .hr{height:1px;background:var(--lift)}
.vcss-root .b{font-weight:500}

/* tracking negativo proporcional ao tamanho: o display ganha peso
   pela tensão entre as letras, não por engordar o traço */
.vcss-root h1,.vcss-root h2,.vcss-root h3{font-family:var(--sans);font-weight:400;margin:0;color:var(--bone);text-wrap:balance}
.vcss-root h1{font-size:clamp(40px,6vw,72px);line-height:1;letter-spacing:-.04em}
.vcss-root h2{font-size:clamp(28px,3.4vw,44px);line-height:1.12;letter-spacing:-.025em}
.vcss-root h3{font-size:20px;line-height:1.2;letter-spacing:-.02em}

/* ── TOPO ────────────────────────────────────────────────────────── */
.vcss-root .hero{position:relative;padding:72px 0 48px;text-align:left}
.vcss-root .hero .haze{display:none}      /* sem brilho ambiente: o Factory é plano */
.vcss-root .hero .wrap{position:relative;z-index:1}
.vcss-root .kicker{
  display:inline-flex;align-items:center;gap:8px;
  margin-bottom:24px;text-decoration:none;
  font-family:var(--mono);font-size:12px;line-height:1;
  letter-spacing:-.02em;text-transform:uppercase;color:var(--stone);
  transition:color .2s;
}
.vcss-root a.kicker:hover{color:var(--bone)}
.vcss-root .kicker i{width:6px;height:6px;border-radius:50%;background:var(--signal);flex:none;font-style:normal}
.vcss-root .hero p.sub{max-width:640px;margin:24px 0 0;color:var(--granite);font-size:16px;line-height:1.5}
.vcss-root .hero .nums{
  display:flex;flex-wrap:wrap;gap:8px 32px;margin-top:32px;
  font-family:var(--mono);font-size:12px;line-height:1;
  letter-spacing:-.02em;text-transform:uppercase;color:var(--stone);
}
.vcss-root .hero .nums b{color:var(--bone);font-weight:400;font-variant-numeric:tabular-nums}

/* ── ALTERNADOR ENTRE AS DUAS COLEÇÕES ──────────────────────────
   São dois links, não abas de JavaScript: cada coleção é uma
   página separada, então cada uma carrega só as suas.           */
.vcss-root .abas{
  display:inline-flex;align-items:center;gap:4px;margin:32px 0 0;
  border:1px solid var(--stroke);border-radius:3px;padding:4px;
}
.vcss-root .abas a{
  display:inline-flex;align-items:center;gap:8px;text-decoration:none;
  border-radius:3px;padding:9px 16px;
  font-family:var(--sans);font-size:14px;font-weight:400;color:var(--granite);
  transition:background .2s,color .2s;
}
.vcss-root .abas a:hover{color:var(--bone)}
.vcss-root .abas a.on{background:var(--chalk);color:var(--canvas)}
.vcss-root .abas a b{
  font-family:var(--mono);font-size:12px;font-weight:400;letter-spacing:-.02em;
  color:inherit;font-variant-numeric:tabular-nums;
}
@media(max-width:520px){
  .vcss-root .abas{display:flex;width:100%}
  .vcss-root .abas a{flex:1;justify-content:center;padding:9px 8px}
}

/* ── ÍNDICE ──────────────────────────────────────────────────────── */
.vcss-root .index{padding:32px 0 8px}
.vcss-root .index .lbl{
  font-family:var(--mono);font-size:12px;line-height:1;letter-spacing:-.02em;
  text-transform:uppercase;color:var(--stone);margin-bottom:16px;
}
.vcss-root .chips{display:flex;flex-wrap:wrap;gap:8px}
.vcss-root .chips a{
  display:inline-flex;align-items:center;gap:8px;
  border:1px solid var(--lift);border-radius:3px;
  padding:8px 12px;text-decoration:none;
  font-family:var(--sans);font-size:14px;color:var(--granite);
  transition:color .2s,border-color .2s;
}
.vcss-root .chips a:hover{color:var(--bone);border-color:var(--stroke)}
.vcss-root .chips a i{
  font-family:var(--mono);font-size:12px;letter-spacing:-.02em;
  color:var(--graphite);font-style:normal;font-variant-numeric:tabular-nums;
}
.vcss-root .chips a:hover i{color:var(--granite)}

/* ── FAIXAS ──────────────────────────────────────────────────────── */
.vcss-root .faixa{padding:96px 0 0}
.vcss-root .faixa .cap{display:flex;align-items:baseline;gap:16px;flex-wrap:wrap}
.vcss-root .faixa .n{
  font-family:var(--mono);font-size:12px;line-height:1;letter-spacing:-.02em;
  text-transform:uppercase;color:var(--signal);
}
.vcss-root .faixa p{color:var(--granite);max-width:640px;margin-top:16px;font-size:16px;line-height:1.5}

/* ── GRADE DE CARTÕES ────────────────────────────────────────────
   O cartão não tem preenchimento: quem o desenha é a hairline.  */
.vcss-root .grade{display:grid;gap:24px;grid-template-columns:1fr;margin-top:32px}
@media(min-width:820px){.vcss-root .grade{grid-template-columns:1fr 1fr}}
.vcss-root .card{
  display:flex;flex-direction:column;
  border:1px solid var(--lift);border-radius:10px;background:none;overflow:hidden;
  content-visibility:auto;contain-intrinsic-size:auto 420px;
}
.vcss-root .card.larga{grid-column:1/-1}
.vcss-root .chead{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:24px 24px 0}
.vcss-root .chead .num{
  font-family:var(--mono);font-size:12px;line-height:1;letter-spacing:-.02em;
  color:var(--stone);border:1px solid var(--lift);border-radius:3px;
  padding:5px 8px;flex:none;font-variant-numeric:tabular-nums;
}
.vcss-root .ctit{padding:16px 24px 0}
.vcss-root .ctit h3{margin-bottom:8px}
.vcss-root .ctit p{color:var(--granite);font-size:14px;line-height:1.43}
.vcss-root .tags{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end}
.vcss-root .tag{
  font-family:var(--mono);font-size:12px;line-height:1;letter-spacing:-.02em;
  text-transform:uppercase;color:var(--stone);
  border:1px solid var(--lift);border-radius:3px;padding:5px 8px;white-space:nowrap;
}
/* acento cromático marcando categoria, não decorando */
.vcss-root .tag.js{color:var(--signal);border-color:var(--lift)}
.vcss-root .tag.hov{color:var(--metric);border-color:var(--lift)}

/* palco onde a animação roda: o poço do instrumento */
.vcss-root .palco{
  position:relative;margin:24px;padding:32px 24px;border-radius:10px;
  min-height:190px;display:flex;align-items:center;justify-content:center;
  gap:16px;flex-wrap:wrap;text-align:center;
  background:var(--lift);
}
.vcss-root .cfoot{
  margin-top:auto;display:flex;align-items:center;justify-content:space-between;
  gap:16px;flex-wrap:wrap;padding:0 24px 24px;
}
.vcss-root .hint{
  font-family:var(--mono);font-size:12px;line-height:1.2;letter-spacing:-.02em;
  color:var(--stone);flex:1 1 160px;min-width:0;
}
.vcss-root .acoes{display:flex;align-items:center;gap:8px;flex:none;margin-left:auto}
.vcss-root .replay{
  font:400 14px var(--sans);cursor:pointer;flex:none;
  border:0;background:var(--lift);color:var(--bone);
  border-radius:3px;padding:9px 14px;
  transition:background .2s;
}
.vcss-root .replay:hover{background:var(--stroke)}
.vcss-root .replay:focus-visible{outline:1px solid var(--bone);outline-offset:2px}

/* botão de copiar o código da animação */
.vcss-root .copiar{
  display:inline-flex;align-items:center;gap:8px;flex:none;cursor:pointer;
  font:400 14px var(--sans);
  border:0;background:var(--chalk);color:var(--canvas);
  border-radius:3px;padding:9px 14px;
  transition:background .2s,color .2s;
}
.vcss-root .copiar svg{width:14px;height:14px}
.vcss-root .copiar:hover{background:var(--bone)}
.vcss-root .copiar:focus-visible{outline:1px solid var(--bone);outline-offset:2px}
/* confirmação é estado, então fala em verde de métrica — sem virar
   botão colorido, que quebraria o cromo monocromático */
.vcss-root .copiar.ok{background:var(--lift);color:var(--metric)}

/* caixa de emergência: aparece só se o navegador bloquear a cópia */
.vcss-root .manual{padding:0 24px 24px}
.vcss-root .manual p{
  font-family:var(--mono);font-size:12px;letter-spacing:-.02em;
  color:var(--stone);margin-bottom:8px;
}
.vcss-root .manual textarea{
  width:100%;height:140px;resize:vertical;
  border:1px solid var(--stroke);border-radius:3px;background:var(--lift);color:var(--bone);
  font-family:var(--mono);font-size:12px;line-height:1.5;padding:16px;
}

/* ── PEÇAS GENÉRICAS USADAS NAS DEMOS ───────────────────────────── */
.vcss-root .peca{
  padding:16px 20px;border-radius:10px;border:1px solid var(--stroke);
  background:var(--canvas);font-family:var(--sans);font-size:14px;color:var(--bone);
}
.vcss-root .pilula{
  display:inline-flex;align-items:center;padding:9px 14px;border-radius:3px;
  border:1px solid var(--stroke);background:var(--canvas);
  font-family:var(--sans);font-size:14px;color:var(--bone);white-space:nowrap;
}
.vcss-root .botao{
  display:inline-flex;align-items:center;justify-content:center;
  height:40px;padding:0 20px;border-radius:3px;border:0;
  background:var(--chalk);color:var(--canvas);
  font-family:var(--sans);font-size:14px;font-weight:400;cursor:pointer;
}
.vcss-root .esfera{
  width:84px;height:84px;border-radius:50%;
  background:var(--graphite);border:1px solid var(--stroke);
}
.vcss-root .quadro{width:150px;height:96px;border-radius:10px;border:1px solid var(--stroke);background:var(--canvas)}
.vcss-root .rotulo{
  font-family:var(--mono);font-size:12px;letter-spacing:-.02em;
  text-transform:uppercase;color:var(--stone);
}
.vcss-root .titulo-demo{font-family:var(--sans);font-size:36px;font-weight:400;color:var(--bone);letter-spacing:-.031em}

/* ── RODAPÉ ─────────────────────────────────────────────────────── */
.vcss-root .foot{border-top:1px solid var(--lift);margin-top:96px;padding:96px 0}
.vcss-root .foot .l{display:flex;flex-wrap:wrap;gap:24px;align-items:center;justify-content:space-between}
.vcss-root .foot .marca{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--mono);font-size:12px;line-height:1;letter-spacing:-.02em;
  text-transform:uppercase;font-weight:500;color:var(--bone);
}
.vcss-root .foot .marca .mk{
  width:24px;height:24px;border-radius:3px;flex:none;
  display:flex;align-items:center;justify-content:center;
  background:var(--lift);border:1px solid var(--stroke);
}
.vcss-root .foot .marca .mk svg{width:12px;height:12px;color:var(--signal)}
.vcss-root .foot p{
  font-family:var(--sans);font-size:14px;color:var(--granite);
  line-height:1.43;margin-top:24px;max-width:640px;
}

/* botão de voltar ao topo */
.vcss-root .topo{
  position:fixed;right:24px;bottom:24px;z-index:60;
  width:40px;height:40px;border-radius:3px;cursor:pointer;
  border:1px solid var(--stroke);background:var(--lift);color:var(--bone);
  display:flex;align-items:center;justify-content:center;
  opacity:0;pointer-events:none;transition:opacity .3s,background .2s;
}
.vcss-root .topo.on{opacity:1;pointer-events:auto}
.vcss-root .topo:hover{background:var(--stroke)}
.vcss-root .topo:focus-visible{outline:1px solid var(--bone);outline-offset:2px}
.vcss-root .topo svg{width:16px;height:16px}

/* ══════════════════════════════════════════════════════════════════
   AS 30 ANIMAÇÕES
   Ordenadas do efeito mais usado na web para o menos comum.
   Cada bloco tem: o estado inicial, a animação e o keyframe.
   As de entrada só rodam quando o cartão recebe a classe .run,
   que o JavaScript adiciona quando ele aparece na tela.
   ══════════════════════════════════════════════════════════════════ */

/* ── 01 · APARECER ────────────────────────────────────────────────
   O mais usado de todos. Só a transparência muda.                  */
.vcss-root .fx-fade{opacity:0}
.vcss-root .run .fx-fade{animation:fade .8s ease-out forwards}
@keyframes fade{to{opacity:1}}

/* ── 02 · SUBIR E APARECER ───────────────────────────────────────
   O padrão de quase todo site moderno ao rolar a página.          */
.vcss-root .fx-up{opacity:0;transform:translateY(26px)}
.vcss-root .run .fx-up{animation:up .7s cubic-bezier(.16,1,.3,1) forwards}
@keyframes up{to{opacity:1;transform:none}}

/* ── 03 · ELEVAR NO HOVER ────────────────────────────────────────
   Transição, não animação: volta sozinha quando o mouse sai.      */
.vcss-root .fx-lift{transition:transform .25s cubic-bezier(.16,1,.3,1),box-shadow .25s,border-color .25s}
.vcss-root .fx-lift:hover{transform:translateY(-6px);box-shadow:0 16px 40px rgba(0,0,0,.55);border-color:rgba(255,255,255,.28)}

/* ── 04 · ENTRAR CRESCENDO ───────────────────────────────────────
   A curva passa de 1 e volta, por isso dá o efeito de mola.       */
.vcss-root .fx-pop{opacity:0;transform:scale(.7)}
.vcss-root .run .fx-pop{animation:pop .55s cubic-bezier(.34,1.56,.64,1) forwards}
@keyframes pop{to{opacity:1;transform:scale(1)}}

/* ── 05 · CASCATA ────────────────────────────────────────────────
   Uma linha resolve qualquer quantidade de itens, via --i.        */
.vcss-root .fx-stagger > *{opacity:0;transform:translateY(20px)}
.vcss-root .run .fx-stagger > *{animation:up .6s cubic-bezier(.16,1,.3,1) forwards;animation-delay:calc(var(--i,0)*90ms)}

/* ── 06 · DESLIZAR DA LATERAL ────────────────────────────────────
   Bom para conversas, avisos e menus.                             */
.vcss-root .fx-slide-l{opacity:0;transform:translateX(-40px)}
.vcss-root .fx-slide-r{opacity:0;transform:translateX(40px)}
.vcss-root .run .fx-slide-l, .vcss-root .run .fx-slide-r{animation:slidein .6s cubic-bezier(.16,1,.3,1) forwards;animation-delay:calc(var(--i,0)*120ms)}
@keyframes slidein{to{opacity:1;transform:none}}

/* ── 07 · PULSAR ─────────────────────────────────────────────────
   Chama atenção sem mover o elemento de lugar.                    */
.vcss-root .fx-pulse{animation:pulse 2s ease-in-out infinite}
@keyframes pulse{
  0%,100%{transform:scale(1);box-shadow:0 0 0 0 rgba(255,255,255,.28)}
  50%{transform:scale(1.04);box-shadow:0 0 0 14px rgba(255,255,255,0)}
}

/* ── 08 · GIRAR ──────────────────────────────────────────────────
   O único caso em que velocidade constante é correta.             */
.vcss-root .fx-spin{
  width:44px;height:44px;border-radius:50%;
  border:3px solid rgba(255,255,255,.14);border-top-color:#fafafa;
  animation:spin .9s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}

/* ── 09 · SUBLINHADO QUE CRESCE ──────────────────────────────────
   Cresce do centro. Truque: escalar em X com origem no meio.      */
.vcss-root .fx-underline{position:relative;text-decoration:none;color:#fff}
.vcss-root .fx-underline::after{
  content:'';position:absolute;left:0;bottom:-6px;width:100%;height:2px;
  background:#fafafa;transform:scaleX(0);transition:transform .35s cubic-bezier(.16,1,.3,1);
}
.vcss-root .fx-underline:hover::after{transform:scaleX(1)}

/* ── 10 · BRILHO QUE ATRAVESSA ───────────────────────────────────
   A faixa fica parada quase todo o ciclo e cruza rápido.          */
.vcss-root .fx-shine{position:relative;overflow:hidden}
.vcss-root .fx-shine::after{
  content:'';position:absolute;top:0;left:-100%;width:55%;height:100%;
  pointer-events:none;transform:skew(-25deg);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.08) 40%,rgba(255,255,255,.32) 50%,rgba(255,255,255,.08) 60%,transparent);
  animation:shine 3.2s ease-in-out infinite;
}
@keyframes shine{0%{left:-100%}28%{left:200%}100%{left:200%}}

/* ── 11 · BARRA DE PROGRESSO ─────────────────────────────────────
   Escala em X, que é mais leve que animar a largura.              */
.vcss-root .fx-bar{height:8px;border-radius:3px;background:rgba(255,255,255,.08);overflow:hidden}
.vcss-root .fx-bar span{display:block;height:100%;border-radius:3px;background:#fafafa;transform-origin:left;transform:scaleX(0)}
.vcss-root .run .fx-bar span{animation:barfill 1.6s cubic-bezier(.16,1,.3,1) forwards;animation-delay:calc(var(--i,0)*160ms)}
@keyframes barfill{to{transform:scaleX(var(--to,.7))}}

/* ── 12 · SANFONA ────────────────────────────────────────────────
   grid-template-rows de 0fr para 1fr abre sem saber a altura.     */
.vcss-root .fx-acc{border:1px solid var(--border);border-radius:10px;overflow:hidden;background:var(--card2)}
.vcss-root .fx-acc + .fx-acc{margin-top:10px}
.vcss-root .fx-acc summary{
  list-style:none;cursor:pointer;padding:14px 16px;
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  font-size:14px;color:#fff;
}
.vcss-root .fx-acc summary::-webkit-details-marker{display:none}
.vcss-root .fx-acc .sign{transition:transform .35s cubic-bezier(.16,1,.3,1);color:var(--fg-dim)}
.vcss-root .fx-acc[open] .sign{transform:rotate(45deg)}
.vcss-root .fx-acc .inner{display:grid;grid-template-rows:0fr;transition:grid-template-rows .38s cubic-bezier(.16,1,.3,1)}
.vcss-root .fx-acc[open] .inner{grid-template-rows:1fr}
.vcss-root .fx-acc .inner > div{overflow:hidden}
.vcss-root .fx-acc .inner p{padding:0 16px 15px;font-size:13.5px;color:var(--fg-muted);text-align:left}
.vcss-root .fx-acc summary{text-align:left}

/* ── 13 · FLUTUAR ────────────────────────────────────────────────
   Amplitude pequena e ciclo longo, senão vira enjoo.              */
.vcss-root .fx-float{animation:float 4s ease-in-out infinite}
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}

/* ── 14 · RESPIRAR ───────────────────────────────────────────────
   Escala mínima somada a um brilho que abre e fecha.              */
.vcss-root .fx-breathe{animation:breathe 4s ease-in-out infinite}
@keyframes breathe{
  0%,100%{transform:scale(1);box-shadow:0 0 44px 6px rgba(255,255,255,.10)}
  50%{transform:scale(1.035);box-shadow:0 0 66px 14px rgba(255,255,255,.20)}
}

/* ── 15 · ESQUELETO CARREGANDO ───────────────────────────────────
   O padrão de carregamento que substituiu o "aguarde".            */
.vcss-root .fx-skel{border-radius:3px;background:
  linear-gradient(90deg,rgba(255,255,255,.05) 25%,rgba(255,255,255,.14) 37%,rgba(255,255,255,.05) 63%);
  background-size:400% 100%;animation:skel 1.4s ease-in-out infinite;
}
@keyframes skel{0%{background-position:100% 50%}100%{background-position:0 50%}}

/* ── 16 · QUICAR ─────────────────────────────────────────────────
   Cada quique é menor, como na física de verdade.                 */
.vcss-root .fx-bounce{animation:bounce 1.6s cubic-bezier(.28,.84,.42,1) infinite}
@keyframes bounce{
  0%{transform:translateY(0)}
  22%{transform:translateY(-34px)}
  40%{transform:translateY(0)}
  54%{transform:translateY(-16px)}
  68%{transform:translateY(0)}
  78%{transform:translateY(-6px)}
  88%,100%{transform:translateY(0)}
}

/* ── 17 · ESTEIRA INFINITA ───────────────────────────────────────
   O conteúdo é duplicado e o trilho anda metade da largura.       */
.vcss-root .fx-marquee{overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent)}
.vcss-root .fx-marquee .trilho{display:flex;gap:14px;width:max-content;animation:marquee 18s linear infinite}
.vcss-root .fx-marquee:hover .trilho{animation-play-state:paused}
@keyframes marquee{to{transform:translateX(-50%)}}

/* ── 18 · CONTADOR DE NÚMEROS ────────────────────────────────────
   Precisa de um pouco de JavaScript para contar. Ver app.js       */
.vcss-root .fx-count{font-family:var(--display);font-size:46px;font-weight:600;color:#fff;line-height:1;font-variant-numeric:tabular-nums}

/* ── 19 · MÁQUINA DE ESCREVER ────────────────────────────────────
   steps() faz o texto pular caractere a caractere.                */
.vcss-root .fx-type{
  display:inline-block;overflow:hidden;white-space:nowrap;
  border-right:2px solid #fafafa;width:0;vertical-align:bottom;
}
.vcss-root .run .fx-type{animation:typing 2.6s steps(32) forwards,caret .8s step-end infinite}
@keyframes typing{to{width:19.5ch}}
@keyframes caret{50%{border-color:transparent}}

/* ── 20 · GRADIENTE EM MOVIMENTO ─────────────────────────────────
   O fundo é maior que o elemento e a posição desliza.             */
.vcss-root .fx-grad{
  background:linear-gradient(120deg,#173052,#2B4A72,#9DB0C8,#2B4A72,#173052);
  background-size:300% 300%;animation:grad 9s ease infinite;
}
@keyframes grad{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}}

/* ── 21 · CORTINA QUE REVELA ─────────────────────────────────────
   O texto não se move: uma faixa passa e o descobre.              */
.vcss-root .fx-curtain{position:relative;display:inline-block;overflow:hidden}
.vcss-root .fx-curtain span{display:inline-block;opacity:0;transform:translateY(100%)}
.vcss-root .fx-curtain::after{
  content:'';position:absolute;inset:0;background:#fafafa;transform:scaleX(0);transform-origin:left;
}
.vcss-root .run .fx-curtain::after{animation:curtain 1s cubic-bezier(.76,0,.24,1) forwards}
.vcss-root .run .fx-curtain span{animation:curtainTxt .01s linear .5s forwards}
@keyframes curtain{
  0%{transform:scaleX(0);transform-origin:left}
  50%{transform:scaleX(1);transform-origin:left}
  50.1%{transform:scaleX(1);transform-origin:right}
  100%{transform:scaleX(0);transform-origin:right}
}
@keyframes curtainTxt{to{opacity:1;transform:none}}

/* ── 22 · TRAÇO QUE SE DESENHA ───────────────────────────────────
   Truque clássico de SVG: tracejado do tamanho da linha.          */
.vcss-root .fx-draw path, .vcss-root .fx-draw circle, .vcss-root .fx-draw polyline{
  stroke-dasharray:var(--len,300);stroke-dashoffset:var(--len,300);
}
.vcss-root .run .fx-draw path, .vcss-root .run .fx-draw circle, .vcss-root .run .fx-draw polyline{
  animation:draw 1.5s cubic-bezier(.65,0,.35,1) forwards;animation-delay:calc(var(--i,0)*220ms);
}
@keyframes draw{to{stroke-dashoffset:0}}

/* ── 23 · CARD QUE VIRA ──────────────────────────────────────────
   Duas faces no mesmo espaço, uma delas já rotacionada.           */
.vcss-root .fx-flip{perspective:1000px;width:190px;height:120px}
.vcss-root .fx-flip .faces{position:relative;width:100%;height:100%;transform-style:preserve-3d;transition:transform .7s cubic-bezier(.16,1,.3,1)}
.vcss-root .fx-flip:hover .faces{transform:rotateY(180deg)}
.vcss-root .fx-flip .face{
  position:absolute;inset:0;backface-visibility:hidden;
  border:1px solid var(--border);border-radius:10px;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--ui);font-size:14px;
}
.vcss-root .fx-flip .front{background:var(--card2);color:#fff}
.vcss-root .fx-flip .back{background:#fafafa;color:var(--canvas);transform:rotateY(180deg);font-weight:600}

/* ── 24 · INCLINAR EM 3D ─────────────────────────────────────────
   O JavaScript só mede o mouse. O CSS faz o resto. Ver app.js     */
.vcss-root .fx-tilt{transition:transform .18s ease-out;transform-style:preserve-3d;will-change:transform}

/* ── 25 · ONDA NO CLIQUE ─────────────────────────────────────────
   Um círculo nasce no ponto clicado e cresce sumindo.             */
.vcss-root .fx-ripple{position:relative;overflow:hidden}
.vcss-root .fx-ripple .onda{
  position:absolute;border-radius:50%;pointer-events:none;
  background:rgba(255,255,255,.35);transform:translate(-50%,-50%) scale(0);
  animation:ripple .65s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes ripple{to{transform:translate(-50%,-50%) scale(1);opacity:0}}

/* ── 26 · DESFOQUE QUE RESOLVE ───────────────────────────────────
   Entra fora de foco e ganha nitidez. Cuidado: filter pesa.       */
.vcss-root .fx-blur{opacity:0;filter:blur(14px);transform:scale(1.04)}
.vcss-root .run .fx-blur{animation:blurin .9s cubic-bezier(.16,1,.3,1) forwards}
@keyframes blurin{to{opacity:1;filter:blur(0);transform:none}}

/* ── 27 · TEXTO EM ONDA ──────────────────────────────────────────
   Cada letra é um elemento com atraso proporcional à posição.     */
.vcss-root .fx-wave span{display:inline-block;animation:wave 1.8s ease-in-out infinite;animation-delay:calc(var(--i,0)*60ms)}
@keyframes wave{0%,60%,100%{transform:translateY(0)}30%{transform:translateY(-12px)}}

/* ── 28 · FORMA QUE SE TRANSFORMA ────────────────────────────────
   border-radius com oito valores vira uma gota que muda.          */
.vcss-root .fx-blob{
  width:120px;height:120px;background:linear-gradient(140deg,#3E5D85,#173052);
  border:1px solid var(--border);
  border-radius:38% 62% 63% 37%/41% 44% 56% 59%;
  animation:blob 8s ease-in-out infinite;
}
@keyframes blob{
  0%,100%{border-radius:38% 62% 63% 37%/41% 44% 56% 59%;transform:rotate(0)}
  34%{border-radius:62% 38% 34% 66%/58% 62% 38% 42%;transform:rotate(6deg)}
  67%{border-radius:44% 56% 61% 39%/36% 51% 49% 64%;transform:rotate(-4deg)}
}

/* ── 29 · TEXTO COM FALHA ────────────────────────────────────────
   Duas cópias deslocadas piscando em tempos diferentes.           */
.vcss-root .fx-glitch{position:relative;color:#fff}
.vcss-root .fx-glitch::before, .vcss-root .fx-glitch::after{
  content:attr(data-txt);position:absolute;inset:0;background:var(--card);
}
.vcss-root .fx-glitch::before{color:var(--signal);animation:glitchA 2.6s steps(2,end) infinite}
.vcss-root .fx-glitch::after{color:#D6F35B;animation:glitchB 2.6s steps(2,end) infinite}
@keyframes glitchA{
  0%,72%,100%{clip-path:inset(0 0 100% 0);transform:none}
  74%{clip-path:inset(12% 0 62% 0);transform:translateX(-3px)}
  78%{clip-path:inset(48% 0 22% 0);transform:translateX(3px)}
  82%{clip-path:inset(0 0 100% 0)}
}
@keyframes glitchB{
  0%,70%,100%{clip-path:inset(0 0 100% 0);transform:none}
  76%{clip-path:inset(60% 0 12% 0);transform:translateX(3px)}
  80%{clip-path:inset(22% 0 54% 0);transform:translateX(-2px)}
  84%{clip-path:inset(0 0 100% 0)}
}

/* ── 30 · ÍMÃ NO CURSOR ──────────────────────────────────────────
   O botão se desloca um pouco na direção do mouse. Ver app.js     */
.vcss-root .fx-magnet{transition:transform .25s cubic-bezier(.16,1,.3,1);will-change:transform}

/* ── ACESSIBILIDADE ──────────────────────────────────────────────
   Quem pediu menos movimento vê tudo parado e completo.           */
@media(prefers-reduced-motion:reduce){
  .vcss-root [class*="fx-"], .vcss-root [class*="fx-"] *, .vcss-root [class*="fx-"]::before, .vcss-root [class*="fx-"]::after{
    animation:none !important;transition:none !important;
    opacity:1 !important;transform:none !important;filter:none !important;
  }
  .vcss-root .fx-type{width:auto !important;border-right:none}
  .vcss-root .fx-bar span{transform:scaleX(var(--to,.7)) !important}
  .vcss-root .fx-curtain::after{display:none}
}

/* ── último recorte: nomes que o tema costuma reivindicar ────── */
.vcss-root .wrap{max-width:1200px !important;margin:0 auto !important;padding:0 24px !important;background:none !important;float:none !important}
.vcss-root .card{border:1px solid var(--lift) !important;border-radius:10px !important;background:none !important}
