/* Gerado por @vooly/tokens. Não editar à mão. */

:root {
  --vly-font-display: 'Manrope', sans-serif;
  --vly-font-body: 'Manrope', sans-serif;
  --vly-text-xs: 11px;
  --vly-text-sm: 12px;
  --vly-text-base: 14px;
  --vly-text-md: 15px;
  --vly-text-lg: 17px;
  --vly-text-xl: 20px;
  --vly-text-2xl: 24px;
  --vly-text-3xl: 30px;
  --vly-text-4xl: 40px;
  --vly-space-0: 0px;
  --vly-space-1: 4px;
  --vly-space-2: 8px;
  --vly-space-3: 12px;
  --vly-space-4: 16px;
  --vly-space-5: 20px;
  --vly-space-6: 24px;
  --vly-space-8: 32px;
  --vly-space-10: 40px;
  --vly-space-12: 48px;
  --vly-space-16: 64px;
  --vly-radius-sm: 8px;
  --vly-radius-md: 12px;
  --vly-radius-lg: 16px;
  --vly-radius-xl: 18px;
  --vly-radius-pill: 999px;
  --vly-duration-fast: 120ms;
  --vly-duration-base: 180ms;
  --vly-duration-slow: 280ms;
  --vly-touch-min: 44px;

  --vly-surface-bg: #F4F6F6;
  --vly-surface-card: #FFFFFF;
  --vly-surface-raised: #FFFFFF;
  --vly-surface-hover: #FAFBFB;
  --vly-text-primary: #123F44;
  --vly-text-secondary: #5E6F70;
  --vly-text-on-accent: #FFFFFF;
  --vly-text-on-fill: #123F44;
  --vly-action-primary: #175A61;
  --vly-action-primary-pressed: #0F4046;
  --vly-action-on-primary: #FFFFFF;
  --vly-action-tint: #DCEBEA;
  --vly-border-subtle: #E3E9EC;
  --vly-border-strong: #78888F;
  --vly-border-rail: #BFD0D0;
  --vly-focus-ring: #175A61;
  --vly-saving-fill: #F0A31B;
  --vly-saving-fill-border: #8A5A00;
  --vly-saving-text: #8A5A00;
  --vly-saving-bg: #FFF6E5;
  --vly-alert-fill: #B83218;
  --vly-alert-fill-border: #B83218;
  --vly-alert-text: #B83218;
  --vly-alert-bg: #FDECEA;
  --vly-success-fill: #146B45;
  --vly-success-fill-border: #146B45;
  --vly-success-text: #146B45;
  --vly-success-bg: #E7F5EE;
  --vly-categoria-voos: #175A61;
  --vly-categoria-hospedagem: #2B5B8F;
  --vly-categoria-alimentacao: #1D6B44;
  --vly-categoria-combustivel: #B87700;
  --vly-categoria-transporte: #5B4494;
  --vly-categoria-outros: #51605F;
  --vly-brand-bar: #175A61;
  --vly-brand-on-bar: #FFFFFF;
  --vly-brand-on-bar-muted: #BFD9DE;
  --vly-brand-on-bar-accent: #FFC46B;
  --vly-brand-bar-pill: #336e74;
  --vly-brand-glow-from: #175A61;
  --vly-brand-glow-via: #3FA9B8;
  --vly-brand-glow-to: #4CC38A;
  --vly-brand-glow-bloom: #3FA9B8;
}

@media (prefers-color-scheme: dark) {
  :root {
    --vly-surface-bg: #0B1418;
    --vly-surface-card: #122029;
    --vly-surface-raised: #17272F;
    --vly-surface-hover: rgba(255,255,255,0.04);
    --vly-text-primary: #E8EEF1;
    --vly-text-secondary: #9FB2BD;
    --vly-text-on-accent: #0B1418;
    --vly-text-on-fill: #0B1418;
    --vly-action-primary: #3FA9B8;
    --vly-action-primary-pressed: #2E8C99;
    --vly-action-on-primary: #0B1418;
    --vly-action-tint: rgba(63,169,184,0.16);
    --vly-border-subtle: #24363F;
    --vly-border-strong: #5E7A86;
    --vly-border-rail: #5E7A86;
    --vly-focus-ring: #7FD4E0;
    --vly-saving-fill: #FFC46B;
    --vly-saving-fill-border: #FFC46B;
    --vly-saving-text: #FFC46B;
    --vly-saving-bg: rgba(255,196,107,0.12);
    --vly-alert-fill: #FF8A73;
    --vly-alert-fill-border: #FF8A73;
    --vly-alert-text: #FF8A73;
    --vly-alert-bg: rgba(255,138,115,0.12);
    --vly-success-fill: #4CC38A;
    --vly-success-fill-border: #4CC38A;
    --vly-success-text: #4CC38A;
    --vly-success-bg: rgba(76,195,138,0.12);
    --vly-categoria-voos: #5FC2CE;
    --vly-categoria-hospedagem: #83B2DE;
    --vly-categoria-alimentacao: #5FCF97;
    --vly-categoria-combustivel: #F0B34D;
    --vly-categoria-transporte: #B9A6E8;
    --vly-categoria-outros: #A6B7B6;
    --vly-brand-bar: #175A61;
    --vly-brand-on-bar: #FFFFFF;
    --vly-brand-on-bar-muted: #BFD9DE;
    --vly-brand-on-bar-accent: #FFC46B;
    --vly-brand-bar-pill: #336e74;
    --vly-brand-glow-from: #175A61;
    --vly-brand-glow-via: #3FA9B8;
    --vly-brand-glow-to: #4CC38A;
    --vly-brand-glow-bloom: #3FA9B8;
  }
}

:root[data-theme='dark'] {
  --vly-surface-bg: #0B1418;
  --vly-surface-card: #122029;
  --vly-surface-raised: #17272F;
  --vly-surface-hover: rgba(255,255,255,0.04);
  --vly-text-primary: #E8EEF1;
  --vly-text-secondary: #9FB2BD;
  --vly-text-on-accent: #0B1418;
  --vly-text-on-fill: #0B1418;
  --vly-action-primary: #3FA9B8;
  --vly-action-primary-pressed: #2E8C99;
  --vly-action-on-primary: #0B1418;
  --vly-action-tint: rgba(63,169,184,0.16);
  --vly-border-subtle: #24363F;
  --vly-border-strong: #5E7A86;
  --vly-border-rail: #5E7A86;
  --vly-focus-ring: #7FD4E0;
  --vly-saving-fill: #FFC46B;
  --vly-saving-fill-border: #FFC46B;
  --vly-saving-text: #FFC46B;
  --vly-saving-bg: rgba(255,196,107,0.12);
  --vly-alert-fill: #FF8A73;
  --vly-alert-fill-border: #FF8A73;
  --vly-alert-text: #FF8A73;
  --vly-alert-bg: rgba(255,138,115,0.12);
  --vly-success-fill: #4CC38A;
  --vly-success-fill-border: #4CC38A;
  --vly-success-text: #4CC38A;
  --vly-success-bg: rgba(76,195,138,0.12);
  --vly-categoria-voos: #5FC2CE;
  --vly-categoria-hospedagem: #83B2DE;
  --vly-categoria-alimentacao: #5FCF97;
  --vly-categoria-combustivel: #F0B34D;
  --vly-categoria-transporte: #B9A6E8;
  --vly-categoria-outros: #A6B7B6;
  --vly-brand-bar: #175A61;
  --vly-brand-on-bar: #FFFFFF;
  --vly-brand-on-bar-muted: #BFD9DE;
  --vly-brand-on-bar-accent: #FFC46B;
  --vly-brand-bar-pill: #336e74;
  --vly-brand-glow-from: #175A61;
  --vly-brand-glow-via: #3FA9B8;
  --vly-brand-glow-to: #4CC38A;
  --vly-brand-glow-bloom: #3FA9B8;
}

:root[data-theme='light'] {
  --vly-surface-bg: #F4F6F6;
  --vly-surface-card: #FFFFFF;
  --vly-surface-raised: #FFFFFF;
  --vly-surface-hover: #FAFBFB;
  --vly-text-primary: #123F44;
  --vly-text-secondary: #5E6F70;
  --vly-text-on-accent: #FFFFFF;
  --vly-text-on-fill: #123F44;
  --vly-action-primary: #175A61;
  --vly-action-primary-pressed: #0F4046;
  --vly-action-on-primary: #FFFFFF;
  --vly-action-tint: #DCEBEA;
  --vly-border-subtle: #E3E9EC;
  --vly-border-strong: #78888F;
  --vly-border-rail: #BFD0D0;
  --vly-focus-ring: #175A61;
  --vly-saving-fill: #F0A31B;
  --vly-saving-fill-border: #8A5A00;
  --vly-saving-text: #8A5A00;
  --vly-saving-bg: #FFF6E5;
  --vly-alert-fill: #B83218;
  --vly-alert-fill-border: #B83218;
  --vly-alert-text: #B83218;
  --vly-alert-bg: #FDECEA;
  --vly-success-fill: #146B45;
  --vly-success-fill-border: #146B45;
  --vly-success-text: #146B45;
  --vly-success-bg: #E7F5EE;
  --vly-categoria-voos: #175A61;
  --vly-categoria-hospedagem: #2B5B8F;
  --vly-categoria-alimentacao: #1D6B44;
  --vly-categoria-combustivel: #B87700;
  --vly-categoria-transporte: #5B4494;
  --vly-categoria-outros: #51605F;
  --vly-brand-bar: #175A61;
  --vly-brand-on-bar: #FFFFFF;
  --vly-brand-on-bar-muted: #BFD9DE;
  --vly-brand-on-bar-accent: #FFC46B;
  --vly-brand-bar-pill: #336e74;
  --vly-brand-glow-from: #175A61;
  --vly-brand-glow-via: #3FA9B8;
  --vly-brand-glow-to: #4CC38A;
  --vly-brand-glow-bloom: #3FA9B8;
}

@font-face{font-family:'Manrope';font-style:normal;font-weight:200 800;font-display:swap;src:url(/assets/manrope.a30ddcd349.woff2) format('woff2')}
/* Selos das companhias: a cor de cada marca, com a letra derivada por contraste. */
.cia-la{background:#16087F;color:#FFFFFF}
.cia-g3{background:#FF7020;color:#152736}
.cia-ad{background:#009BDE;color:#152736}
/* O site institucional.

   Toda cor vem de @vooly/tokens — o bloco de custom properties que abre a folha
   montada, gerado de cssDosTokens(). Aqui não entra hex, rgb() nem nome de cor,
   e o teste recusa se entrar: cor escrita à mão é cor que o gate de contraste
   nunca mediu. As variáveis próprias do site são --site-*, nunca --vly-*.

   A CSP da borda é estrita: nada de style= no HTML e nada de <style>. Por isso
   escalonamento, atraso e proporção de barra moram aqui, por :nth-child, e a
   maquete fica certa mesmo sem JS. O JS só troca classe e atributo, e grava as
   --site-* da paralaxe e da pílula por CSSOM, que a CSP não governa.

   Movimento automático roda uma vez e para (WCAG 2.2.2): nenhum laço. Toda
   animação usa fill-mode both, e o keyframe final é o estado completo — é o que
   deixa o bloco de movimento reduzido, lá embaixo, encurtar tudo para 1 ms sem
   deixar nada pela metade. */

:root {
  color-scheme: light dark;

  /* Altura fixa: a barra muda fundo e sombra ao rolar, nunca a altura — senão
     o conteúdo pula e o scroll-padding das âncoras deixa de bater. */
  --site-altura-barra: 4rem;

  /* ADR 0033: a faixa vai de ponta a ponta e o respiro cresce com a tela. */
  --site-respiro: clamp(1.25rem, 5vw, 7.5rem);
  --site-secao: clamp(4.5rem, 3rem + 6vw, 9rem);

  --site-curva: cubic-bezier(0.2, 0.7, 0.2, 1);
  --site-curva-saida: cubic-bezier(0.16, 1, 0.3, 1);

  /* Sombra tingida pelo texto primário, e em % baixo: no claro ela é um petróleo
     muito escuro, que lê como profundidade e não como cinza sujo. */
  --site-sombra:
    0 1px 2px color-mix(in srgb, var(--vly-text-primary) 5%, transparent),
    0 18px 40px -22px color-mix(in srgb, var(--vly-text-primary) 24%, transparent);
  --site-sombra-palco:
    0 2px 6px color-mix(in srgb, var(--vly-text-primary) 12%, transparent),
    0 30px 60px -26px color-mix(in srgb, var(--vly-text-primary) 60%, transparent);
  --site-sombra-barra:
    0 1px 0 color-mix(in srgb, var(--vly-brand-on-bar) 10%, transparent),
    0 12px 32px -18px color-mix(in srgb, var(--vly-text-primary) 70%, transparent);
  --site-borda-palco: transparent;
  --site-fundo-visual: color-mix(in srgb, var(--vly-action-tint) 62%, transparent);
}

/* No escuro o texto primário é claro, e a mesma sombra viraria halo. Os cartões
   ficam sem sombra; no palco, sobre o petróleo, quem os separa é uma borda. */
@media (prefers-color-scheme: dark) {
  :root {
    --site-sombra: none;
    --site-sombra-palco: none;
    --site-sombra-barra: 0 1px 0 color-mix(in srgb, var(--vly-brand-on-bar) 12%, transparent);
    --site-borda-palco: color-mix(in srgb, var(--vly-brand-on-bar) 14%, transparent);
  }
}

/* ── Base ─────────────────────────────────────────────────────────────── */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* A barra é fixa: sem isto a âncora para com o título escondido embaixo
     dela, e o foco que volta com Shift+Tab também (WCAG 2.4.11). */
  scroll-padding-top: var(--site-altura-barra);
}

@media (prefers-reduced-motion: no-preference) {
  html:not([data-movimento='reduzido']) {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  background: var(--vly-surface-bg);
  color: var(--vly-text-primary);
  font-family: var(--vly-font-body);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
p,
ul,
ol,
dl,
dd {
  margin: 0;
}

/* Com :where, a zeragem não pesa nada: o padding que um componente declara
   (o cartão das linhas é uma <ul>) vence sem disputa de especificidade. */
:where(ul[role='list'], ol[role='list'], .tira, .degraus) {
  list-style: none;
  padding: 0;
}

/* O atributo hidden só esconde elemento HTML; o <svg> do sprite é de outro
   namespace, e sem isto sairia como uma caixa vazia de 300×150 no topo. Os
   <symbol> continuam alcançáveis pelo <use>. */
svg[hidden] {
  display: none;
}

h1,
h2,
h3 {
  font-family: var(--vly-font-display);
  font-weight: 800;
}

a {
  color: inherit;
  text-decoration-thickness: from-font;
  text-underline-offset: 0.22em;
}

::selection {
  background: color-mix(in srgb, var(--vly-action-primary) 22%, transparent);
}

.faixa-marca ::selection,
.barra ::selection,
.rodape ::selection {
  background: var(--vly-brand-on-bar);
  color: var(--vly-brand-bar);
}

/* O ícone de linha do sprite. Sem viewBox aqui: quem o traz é o <symbol>, e o
   <use> o escala ao tamanho do <svg>. Cor por currentColor, sempre. */
.icone {
  display: inline-block;
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}

/* O foco sobre superfície usa o anel do tema. Sobre o petróleo, não: no claro
   focus.ring e brand.bar são o mesmo petróleo, e o anel daria 1:1 — a barra, o
   herói e o contato ficariam sem foco visível. Lá o anel é brand.onBar, o par
   que o gate já aprova sobre a barra (7,86:1). */
:focus-visible {
  outline: 2px solid var(--vly-focus-ring);
  outline-offset: 3px;
}

.barra :focus-visible,
.faixa-marca :focus-visible,
.rodape :focus-visible,
.pular:focus-visible {
  outline-color: var(--vly-brand-on-bar);
}

.pular {
  position: fixed;
  z-index: 100;
  top: 0.625rem;
  left: var(--site-respiro);
  padding: 0.75rem 1.25rem;
  border-radius: var(--vly-radius-pill);
  background: var(--vly-brand-on-bar);
  color: var(--vly-brand-bar);
  font-weight: 700;
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--vly-duration-base) var(--site-curva);
}

.pular:focus {
  transform: none;
}

/* ── Barra ────────────────────────────────────────────────────────────── */

.barra {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: var(--vly-space-4);
  height: var(--site-altura-barra);
  padding-inline: var(--site-respiro);
  background: var(--vly-brand-bar);
  color: var(--vly-brand-on-bar);
  box-shadow: 0 0 0 transparent;
  transition: box-shadow var(--vly-duration-slow) ease;
}

.barra.rolou {
  box-shadow: var(--site-sombra-barra);
}

.marca {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 0.5rem;
  min-height: var(--vly-touch-min);
  border-radius: var(--vly-radius-sm);
  color: var(--vly-brand-on-bar);
  text-decoration: none;
}

/* O "v" do app (Casca.tsx): dois traços brand.onBar e a ponta brand.onBarAccent,
   o único âmbar conferido contra a barra (5,0:1). */
.marca-v {
  width: 1.75rem;
  height: 1.75rem;
  overflow: visible;
  fill: none;
  stroke-width: 21;
  stroke-linecap: round;
}

.marca-v path {
  stroke: var(--vly-brand-on-bar);
}

.marca-v .ponta {
  stroke: var(--vly-brand-on-bar-accent);
}

.marca-nome {
  font-family: var(--vly-font-display);
  font-size: 1.375rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.035em;
}

/* O "v" se desenha na chegada, traço a traço, com a ponta âmbar por último —
   600 ms no total. O primeiro quadro é opacity 0 porque, com ponta redonda,
   um traço de comprimento zero ainda pinta um ponto. */
.barra .marca-v path {
  stroke-dasharray: 1;
  animation: tracar 280ms var(--site-curva) 60ms both;
}

.barra .marca-v path:nth-child(2) {
  animation-duration: 240ms;
  animation-delay: 260ms;
}

.barra .marca-v path:nth-child(3) {
  animation-duration: 160ms;
  animation-delay: 480ms;
}

.navegacao {
  position: relative;
  display: none;
  margin-inline-start: auto;
}

.navegacao ul {
  display: flex;
  gap: 0.125rem;
}

.navegacao a {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  min-height: var(--vly-touch-min);
  padding-inline: 0.875rem;
  border-radius: var(--vly-radius-pill);
  color: var(--vly-brand-on-bar-muted);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--vly-duration-base) ease;
}

/* A âncora ativa é sempre brand.onBar: o onBarMuted sobre a pílula dá 3,92:1 e
   reprova, e o onBar sobre ela dá 5,80:1. */
.navegacao a:hover,
.navegacao a[aria-current='true'] {
  color: var(--vly-brand-on-bar);
}

/* A pílula desliza sob a âncora ativa. Transiciona width, e é a única exceção a
   "só transform e opacity" do site: scaleX achataria a ponta arredondada. A
   posição e a largura chegam do JS em --site-pilula-*. Decorativa: quem diz
   onde se está é o aria-current. */
.pilula {
  position: absolute;
  z-index: 0;
  top: 50%;
  left: 0;
  width: var(--site-pilula-w, 0px);
  height: 2.25rem;
  translate: var(--site-pilula-x, 0px) -50%;
  border-radius: var(--vly-radius-pill);
  background: var(--vly-brand-bar-pill);
  opacity: 0;
  pointer-events: none;
  transition:
    translate 450ms var(--site-curva-saida),
    width 450ms var(--site-curva-saida),
    opacity var(--vly-duration-base) ease;
}

.navegacao.com-pilula .pilula {
  opacity: 1;
}

/* Na primeira aparição a pílula nasce no lugar, em vez de deslizar desde a
   esquerda enquanto ainda está surgindo. */
.navegacao.pilula-parada .pilula {
  transition: opacity var(--vly-duration-base) ease;
}

.barra-entrar {
  display: inline-flex;
  flex: none;
  align-items: center;
  min-height: var(--vly-touch-min);
  margin-inline-start: auto;
  padding-inline: 1.25rem;
  border: 1.5px solid color-mix(in srgb, var(--vly-brand-on-bar) 45%, transparent);
  border-radius: var(--vly-radius-pill);
  color: var(--vly-brand-on-bar);
  font-size: 0.9375rem;
  font-weight: 700;
  text-decoration: none;
  transition:
    background-color var(--vly-duration-base) ease,
    border-color var(--vly-duration-base) ease;
}

.barra-entrar:hover {
  background: var(--vly-brand-bar-pill);
  border-color: var(--vly-brand-on-bar);
}

@media (min-width: 45rem) {
  .navegacao {
    display: block;
  }

  /* Colado à navegação quando ela existe; sem ela (o 404), à direita. */
  .navegacao + .barra-entrar {
    margin-inline-start: var(--vly-space-2);
  }
}

/* ── Tela muito larga ─────────────────────────────────────────────────── */

/* As maquetes crescem inteiras — letra junto — em vez de ficarem do tamanho de
   um celular no meio de uma coluna de mil pixels (ADR 0033: o que sobra vira
   desenho, não vazio). zoom, e não transform: scale, porque zoom ocupa o espaço
   que desenha; os degraus cabem na coluna de cada faixa de largura. */
@media (min-width: 100rem) {
  .palco,
  .maquete {
    zoom: 1.1;
  }
}

@media (min-width: 120rem) {
  .palco,
  .maquete {
    zoom: 1.25;
  }
}

@media (min-width: 150rem) {
  .palco,
  .maquete {
    zoom: 1.4;
  }
}

/* ── Faixas e títulos ─────────────────────────────────────────────────── */

.faixa {
  padding: var(--site-secao) var(--site-respiro);
}

.faixa-marca {
  background: var(--vly-brand-bar);
  color: var(--vly-brand-on-bar);
}

.faixa-cartao {
  background: var(--vly-surface-card);
  border-block: 1px solid var(--vly-border-subtle);
}

h1 {
  margin-top: 1.5rem;
  max-inline-size: 16ch;
  font-size: clamp(2.5rem, 1.6rem + 3.2vw, 4.25rem);
  line-height: 1.04;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

h2 {
  font-size: clamp(1.75rem, 1.3rem + 1.6vw, 2.625rem);
  line-height: 1.1;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

.rotulo {
  color: var(--vly-action-primary);
  font-size: var(--vly-text-sm);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.faixa-marca .rotulo {
  color: var(--vly-brand-on-bar);
}

.cabeca {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-inline-size: 48rem;
  min-width: 0;
}

/* O ritmo: rótulo → título 8px, título → lede 16px, lede → conteúdo 48px. */
.cabeca h2 {
  margin-top: 0.5rem;
}

.cabeca .lede {
  margin-top: 1rem;
}

.lede {
  max-inline-size: 52ch;
  color: var(--vly-text-secondary);
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  font-weight: 500;
  line-height: 1.55;
  text-wrap: pretty;
}

.faixa-marca .lede {
  color: var(--vly-brand-on-bar);
}

.cabeca-centro {
  align-items: center;
  margin-inline: auto;
  text-align: center;
}

/* ── Botões ───────────────────────────────────────────────────────────── */

.acoes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2.5rem;
}

.acoes-centro {
  justify-content: center;
}

/* No telefone os dois botões empilham com a mesma largura, em vez de dois
   comprimentos diferentes alinhados à esquerda. */
@media (max-width: 30rem) {
  .acoes .botao {
    flex: 1 1 100%;
  }
}

.botao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  min-height: 3.25rem;
  padding-inline: 1.625rem;
  border: 1.5px solid transparent;
  border-radius: var(--vly-radius-pill);
  font-family: var(--vly-font-display);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  transition:
    box-shadow var(--vly-duration-slow) var(--site-curva),
    background-color var(--vly-duration-base) ease,
    border-color var(--vly-duration-base) ease;
}

.botao .icone {
  width: 1.125rem;
  height: 1.125rem;
  transition: translate var(--vly-duration-slow) var(--site-curva);
}

.botao:hover .seta {
  translate: 4px 0;
}

/* O CTA claro: brand.onBar com a letra brand.bar, o par do gate. O hover não
   troca a cor — uma cor de hover fora do gate seria um par que ninguém mediu —
   e ganha um halo claro em volta. */
.botao-claro {
  background: var(--vly-brand-on-bar);
  color: var(--vly-brand-bar);
}

.botao-claro:hover {
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--vly-brand-on-bar) 20%, transparent);
}

.botao-contorno {
  border-color: color-mix(in srgb, var(--vly-brand-on-bar) 55%, transparent);
  color: var(--vly-brand-on-bar);
}

.botao-contorno:hover {
  background: var(--vly-brand-bar-pill);
  border-color: var(--vly-brand-on-bar);
}

/* ── Herói ────────────────────────────────────────────────────────────── */

.heroi {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  gap: clamp(3rem, 1rem + 6vw, 6rem);
  padding: clamp(3rem, 2rem + 5vw, 7rem) var(--site-respiro) clamp(4rem, 3rem + 6vw, 8.5rem);
  overflow: clip;
}

@media (min-width: 64rem) {
  .heroi {
    grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
  }
}

.heroi-texto {
  min-width: 0;
}

.heroi-texto > * {
  animation: subir 800ms var(--site-curva-saida) both;
}

.heroi-texto > :nth-child(2) {
  animation-delay: 70ms;
}

.heroi-texto > :nth-child(3) {
  animation-delay: 140ms;
}

.heroi-texto > :nth-child(4) {
  animation-delay: 210ms;
}

.heroi-texto > :nth-child(5) {
  animation-delay: 280ms;
}

/* Todo texto do herói é brand.onBar, inclusive o lede: onBarMuted e o âmbar
   passariam sobre a barra, mas não sobre o brilho do palco se um dia ele
   encostar no texto. */
.selo-heroi {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4375rem 1rem 0.4375rem 0.75rem;
  border-radius: var(--vly-radius-pill);
  background: var(--vly-brand-bar-pill);
  font-size: var(--vly-text-sm);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.selo-heroi .icone {
  width: 1rem;
  height: 1rem;
  rotate: 45deg;
}

/* Este avião é inline, e não do sprite: é a única animação de ícone que roda
   na carga, sem esperar a rolagem, e o traço herdado pelo <use> é o que o
   Chrome às vezes deixa no primeiro quadro (ver o bloco de movimento
   reduzido). Inline, o traço é do próprio path. */
.selo-heroi path {
  stroke-dasharray: 1;
  animation: tracar-icone 1s var(--site-curva) 450ms both;
}

.heroi-lede {
  margin-top: 1.5rem;
  max-inline-size: 52ch;
  font-size: clamp(1.125rem, 1.05rem + 0.35vw, 1.25rem);
  font-weight: 500;
  line-height: 1.55;
  text-wrap: pretty;
}

/* Duas por linha quando cabem: quatro soltas num flex-wrap quebrariam em três
   e uma, com a última sobrando sozinha embaixo. */
.garantias {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.625rem 2rem;
  margin-top: 2.25rem;
  font-size: 0.9375rem;
  font-weight: 600;
}

@media (min-width: 30rem) {
  .garantias {
    grid-template-columns: repeat(2, max-content);
  }
}

.garantias li {
  display: inline-flex;
  align-items: center;
}

/* Um marcador por item, e não um separador entre eles: quando a linha quebra,
   separador deixa um "·" órfão no começo da linha de baixo. É desenho, e não
   caractere, para o leitor de tela não o ler. */
.garantias li::before {
  content: '';
  flex: none;
  width: 5px;
  height: 5px;
  margin-inline-end: 0.625rem;
  border-radius: 50%;
  background: currentColor;
}

/* O palco: três cartões do produto de verdade, no vocabulário do app. */
.palco {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: 1rem;
  width: 100%;
  min-width: 0;
  max-inline-size: 36rem;
  margin-inline: auto;
}

/* O brilho fica atrás do palco e nunca atrás do texto: onBar sobre a bolha
   opaca daria 2,77:1 (glowVia) e 2,22:1 (glowTo). A 30% e com o degradê
   morrendo antes da borda, ele só colore o fundo dos cartões. */
.palco::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: -16% -8%;
  background:
    radial-gradient(
      closest-side at 60% 42%,
      color-mix(in srgb, var(--vly-brand-glow-via) 30%, transparent),
      transparent
    ),
    radial-gradient(
      closest-side at 28% 80%,
      color-mix(in srgb, var(--vly-brand-glow-to) 20%, transparent),
      transparent
    );
  pointer-events: none;
}

.palco::after {
  content: '';
  position: absolute;
  z-index: -2;
  inset: -10% -6%;
  background-image: radial-gradient(
    color-mix(in srgb, var(--vly-brand-on-bar) 14%, transparent) 1px,
    transparent 1.6px
  );
  background-size: 18px 18px;
  -webkit-mask-image: radial-gradient(closest-side, var(--vly-brand-bar), transparent);
  mask-image: radial-gradient(closest-side, var(--vly-brand-bar), transparent);
  pointer-events: none;
}

.cena {
  position: relative;
  min-width: 0;
  padding: 1.125rem 1.25rem;
  border: 1px solid var(--site-borda-palco);
  border-radius: var(--vly-radius-lg);
  background: var(--vly-surface-card);
  box-shadow: var(--site-sombra-palco);
  color: var(--vly-text-primary);
  font-size: 0.875rem;
  line-height: 1.4;
  animation: entrar-cena 800ms var(--site-curva-saida) 300ms both;
  /* A paralaxe usa a propriedade translate, e a entrada usa transform: as duas
     se compõem, e o ponteiro nunca briga com a animação. */
  translate: calc(var(--site-px, 0) * var(--site-profundidade, 0px))
    calc(var(--site-py, 0) * var(--site-profundidade, 0px));
  transition: translate 600ms var(--site-curva-saida);
}

.cena-voo {
  grid-column: 1 / -1;
  grid-row: 1;
  --site-profundidade: 6px;
}

.cena-recibo {
  display: none;
  --site-profundidade: 14px;
}

.cena-aprovado {
  display: none;
  --site-profundidade: 22px;
}

/* Em cascata, e sem um cartão cobrir o conteúdo de outro: a profundidade vem
   do degrau entre eles e da paralaxe, que move cada um num ritmo. */
@media (min-width: 45rem) {
  .cena-voo {
    grid-column: 1 / 12;
  }

  .cena-recibo {
    display: block;
    grid-column: 2 / 8;
    grid-row: 2;
    margin-top: 1rem;
    animation-delay: 420ms;
  }

  .cena-aprovado {
    display: flex;
    grid-column: 8 / 13;
    grid-row: 2;
    align-self: start;
    margin-top: 3.25rem;
    animation-delay: 540ms;
  }
}

.voo-topo {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.voo-nome {
  display: grid;
  flex: 1;
  min-width: 0;
  line-height: 1.25;
}

.voo-nome strong {
  font-size: 0.9375rem;
  font-weight: 800;
}

.voo-nome span {
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
  font-weight: 500;
}

.voo-trecho {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.125rem;
}

.ponta-do-voo {
  display: grid;
  flex: 0 1 auto;
  min-width: 0;
  line-height: 1.2;
}

.ponta-do-voo strong {
  font-family: var(--vly-font-display);
  font-size: 1.375rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.ponta-do-voo span {
  margin-top: 0.1875rem;
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
  font-weight: 500;
}

.ponta-do-voo-fim {
  text-align: right;
}

/* O trilho pontilhado do cartão de voo, em border.rail (decorativo, fora do
   gate de propósito: quem informa é a duração e a escala escritas). */
.trilho {
  position: relative;
  display: grid;
  flex: 1;
  justify-items: center;
  gap: 0.3rem;
  min-width: 4.5rem;
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
  font-weight: 500;
}

/* O avião desenha a rota: a pista tem a largura do trilho e o avião mora na
   ponta dela, então com a mesma duração, atraso e curva, o nariz acompanha a
   ponta do pontilhado que cresce. Pousa no fim, longe da duração e da escala,
   que ficam no meio. */
.trilho-linha {
  justify-self: stretch;
  border-top: 2px dotted var(--vly-border-rail);
  transform-origin: left;
  animation: crescer-x 1.1s var(--site-curva) 950ms both;
}

.aviao-pista {
  position: absolute;
  top: 50%;
  left: 0;
  display: flex;
  justify-content: flex-end;
  width: 100%;
  translate: 0 -50%;
  animation: voar 1.1s var(--site-curva) 950ms both;
}

.aviao {
  box-sizing: content-box;
  width: 1.125rem;
  height: 1.125rem;
  padding: 0.125rem 0.1875rem;
  background: var(--vly-surface-card);
  color: var(--vly-action-primary);
  rotate: 45deg;
}

.voo-rodape {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 1rem;
  padding-top: 0.875rem;
  border-top: 1px solid var(--vly-border-subtle);
}

.sinal {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  color: var(--vly-saving-text);
  font-size: var(--vly-text-xs);
  font-weight: 700;
}

.sinal .icone {
  width: 0.9375rem;
  height: 0.9375rem;
}

.preco {
  font-family: var(--vly-font-display);
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.cena-titulo {
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.campos {
  margin-top: 0.5rem;
}

.campo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding-block: 0.4375rem;
  border-top: 1px solid var(--vly-border-subtle);
}

.campo:first-child {
  border-top: 0;
}

.campo dt {
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
}

.campo dd {
  min-width: 0;
  font-size: 0.8125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* Os campos do recibo entram um a um, como se a leitura os preenchesse. */
.cena-recibo .campo {
  animation: entrar-campo 500ms var(--site-curva-saida) 1050ms both;
}

.cena-recibo .campo:nth-child(2) {
  animation-delay: 1170ms;
}

.cena-recibo .campo:nth-child(3) {
  animation-delay: 1290ms;
}

.cena-recibo .campo:nth-child(4) {
  animation-delay: 1410ms;
}

.cena-aprovado {
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1.25rem 0.875rem 0.875rem;
}

.aprovado-marca {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--vly-success-bg);
  color: var(--vly-success-text);
  animation: surgir-escala 500ms var(--site-curva-saida) 1150ms both;
}

/* O check é inline, e não do sprite, para se desenhar depois do círculo. */
.check-desenho {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.check-desenho path {
  stroke-dasharray: 1;
  animation: tracar 450ms var(--site-curva) 1350ms both;
}

.aprovado-texto {
  display: grid;
  min-width: 0;
  line-height: 1.3;
}

.aprovado-texto strong {
  font-size: 0.9375rem;
  font-weight: 800;
}

.aprovado-texto span {
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
}

/* ── O vocabulário das maquetes (o mesmo do app) ──────────────────────── */

/* O selo da companhia: a cor da marca vem do CSS gerado (.cia-la, .cia-g3,
   .cia-ad). O contorno border.subtle é obrigatório: o azul-marinho da LATAM
   some contra o cartão escuro sem ele. */
.cia {
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--vly-border-subtle);
  border-radius: var(--vly-radius-sm);
  font-size: var(--vly-text-sm);
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* O selo tonal: pílula com ponto. Dentro/fora é dito em texto, e não só na
   cor — daltonismo não pode decidir se o voo cabe na política. */
.selo {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.625rem;
  border-radius: var(--vly-radius-pill);
  font-size: var(--vly-text-xs);
  font-weight: 700;
  line-height: 1.3;
  white-space: nowrap;
}

.selo::before {
  content: '';
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: currentColor;
}

.selo-ok {
  background: var(--vly-success-bg);
  color: var(--vly-success-text);
}

.selo-fora {
  background: var(--vly-alert-bg);
  color: var(--vly-alert-text);
}

.selo-cuidado {
  background: var(--vly-saving-bg);
  color: var(--vly-saving-text);
}

.ponto {
  display: inline-block;
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
}

/* A categoria é elemento gráfico, nunca letra: a legenda é neutra e o ponto
   leva a cor (combustível como letra daria 3,70:1 e reprova). */
.ponto-hospedagem,
.segmento-hospedagem {
  background: var(--vly-categoria-hospedagem);
}

.ponto-alimentacao,
.segmento-alimentacao {
  background: var(--vly-categoria-alimentacao);
}

.ponto-transporte,
.segmento-transporte {
  background: var(--vly-categoria-transporte);
}

.ponto-combustivel,
.segmento-combustivel {
  background: var(--vly-categoria-combustivel);
}

/* ── Produto ──────────────────────────────────────────────────────────── */

.blocos {
  display: grid;
  gap: clamp(4.5rem, 3rem + 6vw, 8rem);
  margin-top: 3rem;
}

.bloco {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  gap: clamp(2rem, 1rem + 3vw, 4rem);
}

@media (min-width: 64rem) {
  .bloco {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  }

  .bloco:nth-child(even) {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  }

  .bloco:nth-child(even) .bloco-texto {
    order: 2;
  }
}

.bloco-texto {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
}

.bloco-texto hgroup {
  margin-top: 1.25rem;
}

.bloco-texto h3 {
  margin-top: 0.5rem;
  font-size: clamp(1.375rem, 1.2rem + 0.6vw, 1.75rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.bloco-texto > p {
  max-inline-size: 44ch;
  margin-top: 1rem;
  color: var(--vly-text-secondary);
  text-wrap: pretty;
}

.ladrilho {
  display: grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: var(--vly-radius-lg);
  background: var(--vly-action-tint);
  color: var(--vly-action-primary);
}

.ladrilho .icone {
  width: 1.5rem;
  height: 1.5rem;
  transition:
    rotate 400ms var(--site-curva),
    scale 400ms var(--site-curva);
}

.bloco:hover .ladrilho .icone {
  rotate: -8deg;
  scale: 1.08;
}

/* O fundo da maquete: a tinta da marca com uma grade de pontos que se apaga
   nas bordas. Enche a coluna — o que sobra na tela larga vira fundo desenhado,
   e não vazio. */
.visual {
  position: relative;
  isolation: isolate;
  display: grid;
  place-items: center;
  min-width: 0;
  padding: clamp(0.875rem, 4vw, 3.5rem);
  overflow: hidden;
  border-radius: 1.5rem;
  background: var(--site-fundo-visual);
  container: visual / inline-size;
}

.visual::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 0;
  background-image: radial-gradient(
    color-mix(in srgb, var(--vly-border-rail) 60%, transparent) 1px,
    transparent 1.5px
  );
  background-size: 20px 20px;
  -webkit-mask-image: radial-gradient(ellipse at center, var(--vly-text-primary) 25%, transparent 78%);
  mask-image: radial-gradient(ellipse at center, var(--vly-text-primary) 25%, transparent 78%);
}

.maquete {
  width: 100%;
  min-width: 0;
  max-inline-size: 34rem;
  padding: clamp(1rem, 0.75rem + 1.5vw, 1.75rem);
  border: 1px solid var(--vly-border-subtle);
  border-radius: var(--vly-radius-lg);
  background: var(--vly-surface-card);
  box-shadow: var(--site-sombra);
  color: var(--vly-text-primary);
  font-size: 0.875rem;
  line-height: 1.45;
}

.m-topo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 0.75rem;
}

.m-titulo {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.01em;
}

.m-discreto {
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
  font-weight: 600;
}

.m-seta {
  width: 0.875rem;
  height: 0.875rem;
  vertical-align: -0.12em;
  color: var(--vly-text-secondary);
}

/* O título de seção do cartão, no desenho do handoff: caixa alta pequena e
   espaçada, em text.secondary. */
.m-rotulo {
  margin-top: 1.375rem;
  margin-bottom: 0.5rem;
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.m-rotulo-junto {
  margin: 0;
}

/* A LinhaDeDados: rótulo à esquerda, valor à direita, número tabular. */
.m-linha {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.625rem;
  border-top: 1px solid var(--vly-border-subtle);
}

.m-linha > :first-child {
  min-width: 0;
  color: var(--vly-text-secondary);
}

.m-linha > :last-child {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.m-total > :first-child {
  color: var(--vly-text-primary);
  font-weight: 700;
}

.m-total > :last-child {
  font-size: 1.0625rem;
  font-weight: 800;
}

/* Busca: a tira "E se mudar um dia?". O dia mais barato é saving.bg com a borda
   saving.fillBorder e a letra saving.text, como TiraDeCalendario.tsx: o âmbar
   de preenchimento contra o cartão daria 2,11:1. */
.tira {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.375rem;
}

.tira li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.125rem;
  min-width: 0;
  padding: 0.5625rem 0.125rem;
  border: 1px solid var(--vly-border-subtle);
  border-radius: var(--vly-radius-md);
  background: var(--vly-surface-raised);
  text-align: center;
}

.tira-dia {
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
  font-weight: 500;
}

.tira-preco {
  font-size: 0.8125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tira-nota {
  font-size: var(--vly-text-xs);
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
}

.tira li.tira-buscada {
  border: 1.5px solid var(--vly-action-primary);
}

.tira-buscada .tira-nota {
  color: var(--vly-action-primary);
}

.tira li.tira-menor {
  border: 1.5px solid var(--vly-saving-fill-border);
  background: var(--vly-saving-bg);
  color: var(--vly-saving-text);
}

/* Herda a cor do dia, e não a fixa: é o que deixa o rótulo acender junto. */
.tira-menor .tira-dia {
  color: inherit;
}

@container visual (max-width: 30rem) {
  .tira {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }

  .tira li:first-child,
  .tira li:last-child {
    display: none;
  }

  .tira li {
    padding-inline: 0;
  }

  .tira-nota {
    font-size: 0.625rem;
  }
}

.par-linha {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-block: 0.625rem;
  border-top: 1px solid var(--vly-border-subtle);
}

.par-linha:first-child {
  border-top: 0;
  padding-top: 0;
}

.par-trecho {
  display: grid;
  flex: 1;
  min-width: 0;
  line-height: 1.3;
}

.par-trecho strong {
  font-weight: 700;
}

.par-trecho span {
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
  font-variant-numeric: tabular-nums;
}

.par-preco {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Política: os chips de perfil. O ativo é action.primary com a letra
   onPrimary; text.secondary sobre a tinta daria 4,30:1 e reprova. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  padding: 0.3125rem 0.75rem;
  border: 1px solid var(--vly-border-subtle);
  border-radius: var(--vly-radius-pill);
  color: var(--vly-text-primary);
  font-size: var(--vly-text-xs);
  font-weight: 700;
}

.chip-ativo {
  border-color: var(--vly-action-primary);
  background: var(--vly-action-primary);
  color: var(--vly-action-on-primary);
}

.maquete-politica .m-topo {
  margin-bottom: 0.875rem;
}

.oferta {
  display: grid;
  /* Cada linha é uma grade própria: com a coluna do selo fixa, o preço cai no
     mesmo lugar em todas, seja o selo "Dentro" ou "Fora". */
  grid-template-columns: auto minmax(0, 1fr) auto 4.75rem;
  align-items: center;
  gap: 0.375rem 0.75rem;
  padding-block: 0.625rem;
  border-top: 1px solid var(--vly-border-subtle);
}

.oferta-voo {
  display: grid;
  min-width: 0;
  line-height: 1.3;
}

.oferta-voo strong {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.oferta-voo span {
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
}

.oferta-preco {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.oferta .selo {
  justify-self: end;
}

.oferta-motivo {
  display: inline-flex;
  grid-column: 2 / -1;
  align-items: center;
  gap: 0.375rem;
  color: var(--vly-alert-text);
  font-size: var(--vly-text-xs);
  font-weight: 600;
}

.oferta-motivo .icone {
  width: 0.875rem;
  height: 0.875rem;
}

@container visual (max-width: 26rem) {
  .oferta {
    grid-template-columns: auto minmax(0, 1fr) auto;
  }

  .oferta .selo {
    grid-column: 3;
    justify-self: end;
  }

  .oferta-motivo {
    grid-column: 1 / 3;
    grid-row: 2;
  }
}

.justificativa {
  display: grid;
  gap: 0.375rem;
  margin-top: 0.875rem;
  padding: 0.75rem 0.875rem;
  border: 1px dashed var(--vly-border-strong);
  border-radius: var(--vly-radius-md);
  background: var(--vly-surface-bg);
}

.justificativa-texto {
  font-weight: 600;
}

/* O cursor parado no fim do texto: diz "campo preenchido à mão" sem piscar —
   piscar para sempre seria um laço. */
.justificativa-texto::after {
  content: '';
  display: inline-block;
  width: 1.5px;
  height: 1.05em;
  margin-inline-start: 2px;
  vertical-align: -0.18em;
  background: var(--vly-action-primary);
}

/* Aprovação: o pedido, os degraus e o orçamento por área. */
.pedido {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.avatar {
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: var(--vly-action-tint);
  color: var(--vly-action-primary);
  font-size: var(--vly-text-xs);
  font-weight: 800;
  letter-spacing: 0.02em;
}

.pedido-quem {
  display: grid;
  flex: 1;
  min-width: 0;
  line-height: 1.3;
}

.pedido-quem strong {
  font-weight: 700;
}

.pedido-quem span {
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
}

.pedido-valor {
  display: grid;
  justify-items: end;
  gap: 0.25rem;
}

.pedido-valor strong {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.degraus {
  display: grid;
}

.degrau {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0.75rem 0.5rem 2rem;
  border-radius: var(--vly-radius-md);
}

.degrau::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 0.75rem;
  width: 0.625rem;
  height: 0.625rem;
  margin-top: -0.3125rem;
  border: 2px solid var(--vly-border-strong);
  border-radius: 50%;
  background: var(--vly-surface-card);
}

/* O fio entre um degrau e o próximo, de ponto a ponto. */
.degrau::after {
  content: '';
  position: absolute;
  top: calc(50% + 0.4375rem);
  left: calc(0.75rem + 0.3125rem - 1px);
  width: 2px;
  height: calc(100% - 0.875rem);
  background: var(--vly-border-subtle);
}

.degrau:last-child::after {
  display: none;
}

.degrau-nome {
  font-weight: 700;
}

.degrau-teto {
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* Sobre a tinta, a letra é action.primary: text.secondary ali reprova. */
.degrau-atual {
  background: var(--vly-action-tint);
}

.degrau-atual::before {
  border-color: var(--vly-action-primary);
  background: var(--vly-action-primary);
}

.degrau-atual .degrau-nome,
.degrau-atual .degrau-teto {
  color: var(--vly-action-primary);
}

.orcamento {
  display: grid;
  gap: 0.875rem;
}

.orcamento li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0.4375rem 0.75rem;
}

.orcamento-area {
  font-weight: 700;
}

.orcamento-valor {
  color: var(--vly-text-secondary);
  font-size: var(--vly-text-xs);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.medida {
  display: block;
  grid-column: 1 / -1;
  height: 6px;
  border-radius: var(--vly-radius-pill);
  background: var(--vly-border-subtle);
}

/* A proporção é regra, e não style= (a CSP o recusa): a barra fica certa mesmo
   sem JS. A animação cresce de 0 até ela por scaleX; a largura em si nunca
   escala, então a ponta arredondada chega redonda. */
.medida-cheia {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--vly-action-primary);
  transform-origin: left;
}

.orcamento li:nth-child(1) .medida-cheia {
  width: 62%;
}

.orcamento li:nth-child(2) .medida-cheia {
  width: 81%;
}

.orcamento li:nth-child(3) .medida-cheia {
  width: 34%;
}

/* Acima de 75% a barra é âmbar, e o âmbar sobre o trilho dá 1,72:1: o
   contorno saving.fillBorder é o que a faz existir, como em Medidas.tsx. */
.orcamento-cuidado .medida-cheia {
  background: var(--vly-saving-fill);
  box-shadow: inset 0 0 0 1px var(--vly-saving-fill-border);
}

.orcamento-cuidado .orcamento-valor {
  color: var(--vly-saving-text);
  font-weight: 600;
}

/* Despesas: a foto do recibo e o que a leitura preencheu. */
.maquete-recibo {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  align-items: start;
  gap: 1.5rem;
}

/* Sem espaço para as duas colunas, a foto sai e os campos ficam: são eles que
   dizem o que a leitura faz. O seletor com a maquete vence o .papel de baixo. */
@container visual (max-width: 28rem) {
  .maquete-recibo {
    grid-template-columns: minmax(0, 1fr);
  }

  .maquete-recibo .papel {
    display: none;
  }
}

.papel {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  aspect-ratio: 3 / 4;
  padding: 1.25rem 1rem;
  overflow: hidden;
  border: 1px solid var(--vly-border-subtle);
  border-radius: var(--vly-radius-md);
  background: var(--vly-surface-bg);
  rotate: -2deg;
}

.papel-cabeca,
.papel-sub,
.papel-item > span {
  display: block;
  flex: none;
  height: 0.375rem;
  border-radius: var(--vly-radius-pill);
  background: color-mix(in srgb, var(--vly-border-rail) 75%, transparent);
}

.papel-cabeca {
  width: 55%;
  height: 0.625rem;
  margin-inline: auto;
  background: var(--vly-border-rail);
}

.papel-sub {
  width: 36%;
  margin: 0 auto 0.625rem;
}

/* Cada item do cupom: a descrição à esquerda, o valor à direita. */
.papel-item {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
}

.papel-item > span:first-child {
  flex-basis: 58%;
}

.papel-item > span:last-child {
  flex-basis: 18%;
}

.papel-item:nth-child(4) > span:first-child {
  flex-basis: 44%;
}

.papel-item:nth-child(5) > span:first-child {
  flex-basis: 66%;
}

.papel-item:nth-child(6) > span:first-child {
  flex-basis: 38%;
}

.papel-corte {
  margin-top: auto;
  border-top: 2px dashed color-mix(in srgb, var(--vly-border-rail) 75%, transparent);
}

.papel-total > span {
  height: 0.625rem;
  background: var(--vly-text-secondary);
}

.papel-total > span:first-child {
  flex-basis: 30%;
}

.papel-total > span:last-child {
  flex-basis: 26%;
}

/* A faixa da leitura passa uma vez pela foto. Parada, ela é invisível — o
   quadro final da animação é o mesmo estado de quem nunca a viu rodar. */
.papel::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 30%;
  border-bottom: 2px solid var(--vly-action-primary);
  background: linear-gradient(
    to bottom,
    transparent,
    color-mix(in srgb, var(--vly-action-primary) 22%, transparent)
  );
  opacity: 0;
}

.leitura {
  min-width: 0;
}

.leitura .campos {
  margin-top: 0.75rem;
}

.leitura dd {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.375rem;
}

.m-botao {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.5rem;
  margin-top: 1rem;
  border-radius: var(--vly-radius-pill);
  background: var(--vly-action-primary);
  color: var(--vly-action-on-primary);
  font-size: 0.875rem;
  font-weight: 700;
}

/* Relatórios: a barra empilhada por categoria e a legenda neutra. */
.m-acao {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  min-height: 2rem;
  padding-inline: 0.75rem;
  border: 1.5px solid var(--vly-action-primary);
  border-radius: var(--vly-radius-pill);
  color: var(--vly-action-primary);
  font-size: var(--vly-text-xs);
  font-weight: 700;
}

.m-acao .icone {
  width: 0.875rem;
  height: 0.875rem;
}

.m-cabeca {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.375rem;
  margin-bottom: 0.625rem;
}

.m-valor {
  font-size: 1.0625rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.empilhada {
  display: flex;
  gap: 2px;
  height: 0.625rem;
  overflow: hidden;
  border-radius: var(--vly-radius-pill);
}

.segmento {
  display: block;
  flex: 1 1 0;
  height: 100%;
  transform-origin: left;
}

/* A fatia de cada categoria, por peso: o gap entre os segmentos sai da conta
   sozinho, e as fatias somam o trilho inteiro. Sem "voos": nenhuma categoria de
   despesa cai nesse balde — o aéreo é reserva, e o site não fala dela. */
.segmento-hospedagem {
  flex-grow: 50;
}

.segmento-alimentacao {
  flex-grow: 27;
}

.segmento-transporte {
  flex-grow: 15;
}

.segmento-combustivel {
  flex-grow: 8;
}

.legenda {
  display: grid;
  margin-top: 0.75rem;
}

.legenda li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.625rem;
  padding-block: 0.3125rem;
  font-size: 0.8125rem;
}

.legenda-pct {
  min-width: 2.75em;
  color: var(--vly-text-secondary);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.legenda strong {
  min-width: 6.5em;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.credito {
  align-items: center;
}

.credito-quem,
.credito-valor {
  display: grid;
  line-height: 1.3;
}

.credito-quem strong {
  color: var(--vly-text-primary);
  font-weight: 700;
}

.credito-quem span {
  font-size: var(--vly-text-xs);
}

.credito-valor {
  justify-items: end;
}

.vence {
  color: var(--vly-saving-text);
  font-size: var(--vly-text-xs);
  font-weight: 700;
}

/* ── Para quem e Segurança: um cartão com quatro linhas ────────────────── */

.dupla {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  gap: clamp(2rem, 1rem + 3vw, 4rem);
}

@media (min-width: 64rem) {
  .dupla {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  }

  /* O título acompanha a leitura das linhas enquanto elas passam. */
  .cabeca-lado {
    position: sticky;
    top: calc(var(--site-altura-barra) + 2.5rem);
  }
}

.linhas {
  min-width: 0;
  padding-inline: clamp(1.25rem, 0.75rem + 2vw, 2.25rem);
  border: 1px solid var(--vly-border-subtle);
  border-radius: var(--vly-radius-lg);
  background: var(--vly-surface-card);
  box-shadow: var(--site-sombra);
  container: linhas / inline-size;
}

.linha {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0.25rem 1rem;
  padding-block: 1.375rem;
  border-top: 1px solid var(--vly-border-subtle);
}

.linha:first-child {
  border-top: 0;
}

.linha-icone {
  display: grid;
  grid-row: span 2;
  align-self: start;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--vly-radius-md);
  background: var(--vly-action-tint);
  color: var(--vly-action-primary);
}

.linha-icone .icone {
  transition: translate 400ms var(--site-curva);
}

.linha:hover .linha-icone .icone {
  translate: 0 -2px;
}

.linha h3 {
  font-size: 1.0625rem;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.linha p {
  max-inline-size: 44ch;
  color: var(--vly-text-secondary);
  text-wrap: pretty;
}

/* Com espaço, rótulo à esquerda e frase à direita, como a LinhaDeDados; sem
   espaço, a frase desce para baixo do rótulo. Mede o cartão, não a tela. */
@container linhas (min-width: 34rem) {
  .linha {
    grid-template-columns: auto minmax(7rem, 9.5rem) minmax(0, 1fr);
    gap: 1.25rem;
  }

  .linha-icone {
    grid-row: auto;
    align-self: center;
  }
}

/* ── Como funciona ────────────────────────────────────────────────────── */

.passos {
  display: grid;
  gap: 2rem;
  margin-top: 3rem;
}

.passo {
  position: relative;
  min-width: 0;
  padding-left: 4rem;
}

.passo-numero {
  position: absolute;
  top: -0.125rem;
  left: 0;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: var(--vly-action-primary);
  box-shadow: 0 0 0 6px var(--vly-surface-card);
  color: var(--vly-action-on-primary);
  font-family: var(--vly-font-display);
  font-size: 1.0625rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.passo h3 {
  padding-top: 0.5rem;
  font-size: 1.125rem;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.passo p {
  max-inline-size: 40ch;
  margin-top: 0.375rem;
  color: var(--vly-text-secondary);
  text-wrap: pretty;
}

/* A linha que liga os passos: vertical no estreito, horizontal no largo. */
.passo:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 3.25rem;
  bottom: -1.375rem;
  left: calc(1.375rem - 1px);
  width: 2px;
  border-radius: 2px;
  background: var(--vly-border-rail);
  transform-origin: top;
}

@media (min-width: 64rem) {
  .passos {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 2.5rem;
  }

  .passo {
    padding-top: 4.25rem;
    padding-left: 0;
  }

  .passo-numero {
    top: 0;
  }

  .passo h3 {
    padding-top: 0;
  }

  .passo:not(:last-child)::after {
    top: calc(1.375rem - 1px);
    right: -1.5rem;
    bottom: auto;
    left: 3.75rem;
    width: auto;
    height: 2px;
    transform-origin: left;
  }
}

/* ── Contato ──────────────────────────────────────────────────────────── */

.contato {
  display: grid;
  justify-items: center;
}

/* O anel: um conic-gradient num ::before que gira por transform — camada de
   composição, sem @property e sem repintar a cada quadro. O cartão cobre o
   miolo e sobra a borda de 2px. Dá uma volta ao entrar na tela (transform) e
   depois só gira com o ponteiro ou o foco em cima (rotate): as duas
   propriedades se compõem e uma não interrompe a outra. */
.anel {
  position: relative;
  isolation: isolate;
  width: 100%;
  max-inline-size: 48rem;
  padding: 2px;
  overflow: hidden;
  border-radius: 1.75rem;
  background: color-mix(in srgb, var(--vly-brand-on-bar) 14%, transparent);
}

.anel::before {
  content: '';
  position: absolute;
  z-index: -1;
  top: 50%;
  left: 50%;
  width: max(200%, 48rem);
  aspect-ratio: 1;
  translate: -50% -50%;
  background: conic-gradient(
    transparent 0turn,
    var(--vly-brand-glow-via) 0.12turn,
    var(--vly-brand-glow-to) 0.24turn,
    transparent 0.38turn,
    transparent 0.5turn,
    var(--vly-brand-glow-via) 0.62turn,
    var(--vly-brand-glow-to) 0.74turn,
    transparent 0.88turn
  );
  rotate: 0turn;
  transition: rotate 2.4s var(--site-curva);
}

.anel:hover::before,
.anel:focus-within::before {
  rotate: 1turn;
}

.anel-cartao {
  display: grid;
  justify-items: center;
  padding: clamp(2.25rem, 1.5rem + 4vw, 4.5rem) clamp(1.25rem, 5vw, 4.5rem);
  border-radius: calc(1.75rem - 2px);
  background: var(--vly-brand-bar);
  text-align: center;
}

.contato .lede {
  margin-inline: auto;
}

/* O "v" da marca abre o cartão, e se desenha de novo quando a faixa entra. */
.contato-v {
  width: 2.75rem;
  height: 2.75rem;
  margin-bottom: 1.5rem;
}

.contato-email {
  margin-top: 1.75rem;
  font-size: 1.125rem;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.contato-email a {
  text-decoration-color: color-mix(in srgb, var(--vly-brand-on-bar) 45%, transparent);
  text-underline-offset: 0.3em;
  transition: text-decoration-color var(--vly-duration-base) ease;
}

.contato-email a:hover {
  text-decoration-color: currentColor;
}

.contato-cliente {
  margin-top: 0.75rem;
  font-size: 0.9375rem;
  font-weight: 500;
}

.contato-cliente a {
  font-weight: 700;
}

/* ── Rodapé ───────────────────────────────────────────────────────────── */

.rodape {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 2rem;
  padding: 2rem var(--site-respiro) 2.5rem;
  border-top: 1px solid color-mix(in srgb, var(--vly-brand-on-bar) 12%, transparent);
  background: var(--vly-brand-bar);
  color: var(--vly-brand-on-bar-muted);
  font-size: 0.9375rem;
}

.marca-rodape .marca-v {
  width: 1.5rem;
  height: 1.5rem;
}

.marca-rodape .marca-nome {
  font-size: 1.1875rem;
}

.rodape-direitos {
  margin-inline-start: auto;
  font-variant-numeric: tabular-nums;
}

/* ── A página 404 ─────────────────────────────────────────────────────── */

/* A página inteira é petróleo: numa janela mais alta que ela, o fundo claro do
   body apareceria como uma faixa embaixo do rodapé. */
.pagina-404 {
  background: var(--vly-brand-bar);
}

.perdido {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  min-height: calc(100svh - var(--site-altura-barra) - 6.5rem);
  padding: clamp(3rem, 2rem + 6vw, 7rem) var(--site-respiro);
}

.perdido-rota {
  display: flex;
  align-items: center;
  gap: 1rem;
  width: 100%;
  max-inline-size: 26rem;
  margin-bottom: 2.5rem;
}

.perdido-ponta {
  font-family: var(--vly-font-display);
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.perdido .trilho-linha {
  border-top-color: color-mix(in srgb, var(--vly-brand-on-bar) 45%, transparent);
}

.perdido .aviao {
  background: var(--vly-brand-bar);
  color: var(--vly-brand-on-bar);
}

/* ── Movimento ao rolar ───────────────────────────────────────────────── */

/* Só esconde sob html.js. Sem JS a classe nunca entra e tudo aparece, com as
   barras e os selos no estado final — a maquete não depende do script. O que já
   estava na tela quando o script rodou é marcado antes de a classe entrar. */
/* A transição mora só no estado visível: declarada aqui, cada elemento abaixo
   da dobra animaria de visível para oculto no instante em que a classe js
   entra — dezenas de transições de 800 ms na carga, fora da tela, para nada. */
html.js .revelar,
html.js .revelar-filhos > * {
  opacity: 0;
  transform: translateY(14px);
}

html.js .revelar:not(.visivel),
html.js .revelar-filhos:not(.visivel) > * {
  will-change: opacity, transform;
}

html.js .revelar.visivel,
html.js .revelar-filhos.visivel > * {
  opacity: 1;
  transform: none;
  transition:
    opacity 800ms var(--site-curva-saida),
    transform 800ms var(--site-curva-saida);
}

html.js .revelar-filhos.visivel > :nth-child(2) {
  transition-delay: 110ms;
}

html.js .revelar-filhos.visivel > :nth-child(3) {
  transition-delay: 220ms;
}

html.js .revelar-filhos.visivel > :nth-child(4) {
  transition-delay: 330ms;
}

/* Os ícones se desenham ao entrar: stroke-dashoffset no <use>, herdado pelos
   traços do símbolo, cada um com pathLength="1". */
html.js .visivel .ladrilho use,
html.js .visivel .linha-icone use {
  stroke-dasharray: 1;
  animation: tracar-icone 1.1s var(--site-curva) 250ms both;
}

html.js .linhas.visivel .linha:nth-child(2) use {
  animation-delay: 360ms;
}

html.js .linhas.visivel .linha:nth-child(3) use {
  animation-delay: 470ms;
}

html.js .linhas.visivel .linha:nth-child(4) use {
  animation-delay: 580ms;
}

/* Busca: os dias entram em onda e o mais barato acende por último. */
html.js .visivel .tira li {
  animation: entrar-campo 450ms var(--site-curva-saida) 300ms both;
}

html.js .visivel .tira li:nth-child(2) {
  animation-delay: 350ms;
}

html.js .visivel .tira li:nth-child(3) {
  animation-delay: 400ms;
}

html.js .visivel .tira li:nth-child(5) {
  animation-delay: 500ms;
}

html.js .visivel .tira li:nth-child(6) {
  animation-delay: 550ms;
}

html.js .visivel .tira li:nth-child(7) {
  animation-delay: 600ms;
}

/* Duas animações que não disputam propriedade: a entrada mexe em opacidade e
   posição, o acender só em cor. */
html.js .visivel .tira li.tira-menor {
  animation:
    entrar-campo 450ms var(--site-curva-saida) 450ms both,
    acender 900ms var(--site-curva) 950ms both;
}

html.js .visivel .tira-menor .tira-nota {
  animation: surgir-escala 400ms var(--site-curva-saida) 1350ms both;
}

html.js .visivel .par-linha {
  animation: entrar-campo 500ms var(--site-curva-saida) 1100ms both;
}

html.js .visivel .par-linha:nth-child(2) {
  animation-delay: 1220ms;
}

/* Política: o fora da regra se marca depois de a lista aparecer. */
html.js .visivel .oferta-fora .selo {
  animation: surgir-escala 450ms var(--site-curva-saida) 700ms both;
}

html.js .visivel .oferta-motivo {
  animation: entrar-campo 500ms var(--site-curva-saida) 850ms both;
}

/* Aprovação: o degrau do pedido acende e as barras crescem até a proporção. */
html.js .visivel .degrau-atual {
  animation: acender-degrau 700ms var(--site-curva) 500ms both;
}

html.js .visivel .medida-cheia {
  animation: crescer-x 1s var(--site-curva) 450ms both;
}

html.js .visivel .orcamento li:nth-child(2) .medida-cheia {
  animation-delay: 580ms;
}

html.js .visivel .orcamento li:nth-child(3) .medida-cheia {
  animation-delay: 710ms;
}

/* Despesas: a leitura passa pela foto, e os campos entram em seguida. */
html.js .visivel .papel::after {
  animation: varrer 1.5s var(--site-curva) 300ms both;
}

html.js .visivel .leitura .m-linha {
  animation: entrar-campo 500ms var(--site-curva-saida) 900ms both;
}

html.js .visivel .leitura .m-linha:nth-child(2) {
  animation-delay: 1020ms;
}

html.js .visivel .leitura .m-linha:nth-child(3) {
  animation-delay: 1140ms;
}

html.js .visivel .leitura .m-linha:nth-child(4) {
  animation-delay: 1260ms;
}

html.js .visivel .leitura .m-linha:nth-child(5) {
  animation-delay: 1380ms;
}

html.js .visivel .leitura .selo {
  animation: surgir-escala 450ms var(--site-curva-saida) 1550ms both;
}

/* Relatórios: as fatias crescem uma atrás da outra. */
html.js .visivel .segmento {
  animation: crescer-x 700ms var(--site-curva) 350ms both;
}

html.js .visivel .segmento:nth-child(2) {
  animation-delay: 450ms;
}

html.js .visivel .segmento:nth-child(3) {
  animation-delay: 550ms;
}

html.js .visivel .segmento:nth-child(4) {
  animation-delay: 650ms;
}

html.js .visivel .segmento:nth-child(5) {
  animation-delay: 750ms;
}

html.js .visivel .vence {
  animation: surgir-escala 450ms var(--site-curva-saida) 1000ms both;
}

/* Como funciona: cada número surge e a linha até o próximo se desenha. */
html.js .passos.visivel > .passo:nth-child(2) {
  transition-delay: 450ms;
}

html.js .passos.visivel > .passo:nth-child(3) {
  transition-delay: 900ms;
}

html.js .passos.visivel > .passo:nth-child(4) {
  transition-delay: 1350ms;
}

html.js .passos.visivel .passo-numero {
  animation: surgir-escala 500ms var(--site-curva-saida) 100ms both;
}

html.js .passos.visivel .passo:nth-child(2) .passo-numero {
  animation-delay: 550ms;
}

html.js .passos.visivel .passo:nth-child(3) .passo-numero {
  animation-delay: 1000ms;
}

html.js .passos.visivel .passo:nth-child(4) .passo-numero {
  animation-delay: 1450ms;
}

html.js .passos.visivel .passo:not(:last-child)::after {
  animation: crescer-y 450ms var(--site-curva) 250ms both;
}

html.js .passos.visivel .passo:nth-child(2)::after {
  animation-delay: 700ms;
}

html.js .passos.visivel .passo:nth-child(3)::after {
  animation-delay: 1150ms;
}

@media (min-width: 64rem) {
  html.js .passos.visivel .passo:not(:last-child)::after {
    animation-name: crescer-x;
  }
}

/* Contato: o anel dá uma volta quando a faixa entra, e o "v" se desenha. */
html.js .anel.visivel::before {
  animation: anel-volta 1.8s var(--site-curva) 200ms both;
}

html.js .anel.visivel .contato-v path {
  stroke-dasharray: 1;
  animation: tracar 320ms var(--site-curva) 450ms both;
}

html.js .anel.visivel .contato-v path:nth-child(2) {
  animation-delay: 700ms;
}

html.js .anel.visivel .contato-v path:nth-child(3) {
  animation-duration: 200ms;
  animation-delay: 950ms;
}

/* ── Keyframes ────────────────────────────────────────────────────────── */

/* Os que crescem declaram só o começo: o fim implícito é o valor da regra, que
   já é o estado completo — a barra na proporção dela, o traço inteiro. */

@keyframes tracar {
  from {
    stroke-dashoffset: 1;
    opacity: 0;
  }

  12% {
    opacity: 1;
  }

  to {
    stroke-dashoffset: 0;
    opacity: 1;
  }
}

@keyframes tracar-icone {
  from {
    stroke-dashoffset: 1;
    opacity: 0;
  }

  8% {
    opacity: 1;
  }

  to {
    stroke-dashoffset: 0;
    opacity: 1;
  }
}

@keyframes subir {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

@keyframes entrar-cena {
  from {
    opacity: 0;
    transform: translateY(22px) scale(0.97);
  }
}

@keyframes entrar-campo {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
}

@keyframes surgir-escala {
  from {
    opacity: 0;
    transform: scale(0.6);
  }
}

@keyframes crescer-x {
  from {
    transform: scaleX(0);
  }
}

@keyframes crescer-y {
  from {
    transform: scaleY(0);
  }
}

@keyframes voar {
  from {
    opacity: 0;
    transform: translateX(-100%);
  }

  12% {
    opacity: 1;
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes acender {
  from {
    border-color: var(--vly-border-subtle);
    background-color: var(--vly-surface-raised);
    color: var(--vly-text-primary);
  }
}

@keyframes acender-degrau {
  from {
    background-color: transparent;
  }
}

@keyframes varrer {
  from {
    opacity: 1;
    transform: translateY(-100%);
  }

  85% {
    opacity: 1;
  }

  to {
    opacity: 0;
    transform: translateY(340%);
  }
}

@keyframes anel-volta {
  from {
    transform: rotate(-1turn);
  }
}

/* ── Movimento reduzido ───────────────────────────────────────────────── */

/* Quem pediu menos movimento recebe o estado final na hora: 1 ms em vez de
   zero para os eventos de fim de animação ainda dispararem, e sem atraso —
   senão a ponta do "v" e o escalonamento continuariam esperando. O bloco vale
   pela preferência do sistema e pelo atributo que o JS põe quando ela casa. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }

  .cena {
    translate: none !important;
  }

  use {
    animation: none !important;
  }
}

html[data-movimento='reduzido'] *,
html[data-movimento='reduzido'] *::before,
html[data-movimento='reduzido'] *::after {
  animation-duration: 1ms !important;
  animation-delay: 0s !important;
  animation-iteration-count: 1 !important;
  transition-duration: 1ms !important;
  transition-delay: 0s !important;
  scroll-behavior: auto !important;
}

html[data-movimento='reduzido'] .cena {
  translate: none !important;
}

/* O ícone do sprite fica sem animação nenhuma, em vez de 1 ms. O traço dele é
   herdado do <use> pela cópia do símbolo, e o Chrome não repassa à cópia o fim
   de uma animação que acaba entre dois quadros: o ícone ficava parado no
   primeiro quadro, invisível. Sem animação, nasce desenhado. */
html[data-movimento='reduzido'] use {
  animation: none !important;
}

/* ── Impressão e cores forçadas ───────────────────────────────────────── */

@media print {
  .barra {
    position: static;
  }

  html.js .revelar,
  html.js .revelar-filhos > * {
    opacity: 1 !important;
    transform: none !important;
  }
}

@media (forced-colors: active) {
  .selo,
  .chip,
  .cia,
  .tira li,
  .medida,
  .empilhada,
  .ponto {
    border: 1px solid CanvasText;
  }
}
