/* Vita Hair — folha única, mobile first.
 *
 * A quebra para telas largas acontece em 900px, uma vez, em @media no fim de
 * cada bloco. O piso é 360px de largura: nada aqui usa largura fixa maior que
 * isso fora de media query.
 *
 * Duas famílias, dois papéis: Fraunces nos títulos e nos números de preço,
 * Figtree em tudo que se lê corrido. A ousadia está no rosa do accent e nas
 * duas faixas preto sobre rosa; o resto fica quieto.
 *
 * Movimento só como resposta a uma ação: hover, foco, abrir um <details>.
 * Nada entra em cena com fade.
 */

/* Os três temas — cores, tipografia e medidas — moram em /tokens.css, carregado
 * antes desta folha. Ver o comentário no topo de lá. */


*,
*::before,
*::after {
  box-sizing: border-box;
}

/* app.js esconde e revela quase tudo pelo atributo `hidden`: os quatro painéis
 * do checkout, o bloco de entrega, a lista de fretes, a linha de frete do
 * resumo, os avisos e o botão do desfecho. O `display: none` de `hidden` vem da
 * folha do navegador, e qualquer `display` declarado aqui — `flex` em `.panel`,
 * por exemplo — ganha dele por ser regra de autor. Sem esta linha os quatro
 * painéis apareceriam juntos. */
[hidden] {
  display: none !important;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  overflow-wrap: break-word;
  /* Sem `overflow-x` aqui, de propósito. Tudo que passa da borda — as camadas de
   * fundo, a faixa inclinada, a palavra gigante — é recortado pelo próprio
   * invólucro. Recortar no <body> criaria caixa de rolagem, e aí o header
   * `sticky` pararia de colar e o fundo `fixed` poderia ser cortado. */
}

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.1;
}

p {
  margin: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

img,
svg {
  max-width: 100%;
}

a {
  color: var(--accent-text);
}

a:hover {
  color: var(--accent-text-hover);
}

/* Um anel só, em todo lugar, e sempre visível — inclusive sobre fundo escuro,
 * onde o accent sozinho não se destaca. */
:focus-visible {
  outline: var(--focus-width) solid var(--accent-text);
  outline-offset: 2px;
  border-radius: 6px;
}

.band--dark :focus-visible,
.band--last :focus-visible,
.foot :focus-visible,
.offer :focus-visible {
  outline-color: var(--accent-light);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute;
  left: -9999px;
  z-index: 10;
}

.skip:focus {
  left: var(--gutter);
  top: 12px;
  padding: 12px 18px;
  background: var(--invert-bg);
  color: var(--invert-ink);
  border-radius: 999px;
  text-decoration: none;
}

/* ---------------------------------------------------------------------------
 * Medidas comuns
 * ------------------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* `position: relative` porque cada faixa ancora a própria onda de divisória,
 * que fica acima dela (`bottom: 100%`). Nenhuma faixa recorta o transbordo: o
 * que precisa de recorte tem invólucro próprio. */
.band {
  position: relative;
  padding: var(--band-pad) 0;
}

/* A faixa que o card de compra invade reserva o espaço da invasão no respiro de
 * baixo. Sem isto o card — que é opaco, com z-index 2 e sombra — cobria a última
 * linha do texto da seção de cima, e o resultado parecia texto cortado no meio de
 * uma palavra. A conta: o card subia 110px (72px no telefone) e a faixa só tinha
 * 88px (48px) de respiro, então sobravam ~22px de conteúdo coberto — uma linha. */
.band--overlapped {
  padding-bottom: calc(var(--band-pad) + var(--overlap));
}

.band--white {
  background: var(--surface);
  --wave-fill: var(--surface);
}

.band--soft {
  background: var(--bg-soft);
  --wave-fill: var(--bg-soft);
}

.band--dark {
  background: var(--invert-bg);
  color: var(--invert-ink);
  --wave-fill: var(--invert-bg);
  /* Contexto de empilhamento próprio, para a palavra gigante em `z-index: -1`
   * ficar acima deste fundo preto e abaixo do texto. Sem isto ela escaparia para
   * o contexto da raiz e desapareceria atrás da faixa. */
  isolation: isolate;
}

.band--last {
  padding: 8px 0 48px;
}

.section-title {
  font-size: clamp(1.75rem, 7vw, 2rem);
  max-width: 34ch;
}

/* ---------------------------------------------------------------------------
 * Botões
 *
 * Quatro pesos: loud (accent), light (branco sobre escuro), quiet (contornado)
 * e plain (só texto). Todos chegam a 44px de altura.
 * ------------------------------------------------------------------------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: var(--touch);
  padding: 12px 24px;
  border: 2px solid transparent;
  border-radius: 999px;
  font: inherit;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.button svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.button--loud {
  background: var(--accent);
  color: var(--accent-on);
}

.button--loud:hover {
  background: var(--accent-hover-bg);
  color: var(--accent-hover-ink);
}

.button--light {
  background: var(--invert-ink);
  color: var(--invert-bg);
}

.button--light:hover {
  background: var(--on-accent-soft);
  color: var(--invert-bg);
}

.button--quiet {
  background: transparent;
  border-color: var(--accent-text);
  color: var(--accent-text);
}

.button--quiet:hover {
  background: var(--accent);
  color: var(--accent-on);
}

.button--plain {
  background: transparent;
  color: var(--muted);
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.button--plain:hover {
  color: var(--ink);
}

.button--wide {
  width: 100%;
}

.button--small {
  padding: 10px 18px;
  font-size: 0.9375rem;
}

.button[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ---------------------------------------------------------------------------
 * Aviso e header
 * ------------------------------------------------------------------------- */

.bulletin {
  padding: 10px var(--gutter);
  background: var(--invert-bg);
  color: var(--invert-ink);
  font-size: 0.8125rem;
  font-weight: 500;
  text-align: center;
}

/* Cola no topo e encolhe ao rolar. `is-stuck` vem de landing-fx.js; sem JS o
 * header fica na versão alta, opaca, que é a legível. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 64px;
  padding: 8px var(--gutter);
  border-bottom: var(--border-width) solid var(--line);
  background: var(--bg);
  transition: min-height 0.25s ease, background-color 0.25s ease,
    box-shadow 0.25s ease;
}

.topbar.is-stuck {
  min-height: 54px;
  background: var(--topbar-solid);
  box-shadow: 0 10px 30px -18px var(--shadow-soft);
}

/* O vidro só entra onde o navegador sabe desfocar. Onde não sabe, o fundo
 * translúcido acima já garante o contraste do texto. */
@supports (backdrop-filter: blur(1px)) {
  .topbar.is-stuck {
    background: var(--topbar-glass);
    backdrop-filter: var(--topbar-blur);
  }
}

/* Marca ------------------------------------------------------------------
 *
 * Um arquivo só em todo lugar: `logo-vita-hair*.png`, feito para fundo escuro
 * (rosa do ícone e do nome a mais de 8:1 sobre os fundos escuros do site,
 * tagline branca), com alpha reto e sem halo — ver scripts/extract-logo.mjs.
 *
 * Funciona porque a logo nunca pousa em fundo claro: o header é escuro nos três
 * temas (no claro, pelos tokens redefinidos em "HEADER NO TEMA CLARO", no topo da
 * folha) e o rodapé é `--invert-bg`, escuro nos três. A variante do cliente
 * para fundo claro (docs/design/product-originals/logo-vitahair-fundobranco.png)
 * foi testada no header claro e o rosa dela, o mesmo tom, dava 1,8:1 — sumia.
 * Fica guardada para quando a marca precisar aparecer sobre claro.
 *
 * Dois recortes: compacto (ícone + "VITA HAIR") nos headers, completo (com a
 * tagline) no rodapé.
 */
.brand {
  display: inline-flex;
  text-decoration: none;
  transition: transform 0.25s ease;
}

.brand__mark {
  display: inline-flex;
  align-items: center;
}

/* O compacto empilha o ícone sobre o nome, então a altura é o que decide se
 * "VITA HAIR" se lê: 38px deixam o nome com ~9px de altura de letra, e ainda
 * cabem no header de 64px. Ao rolar, o header encolhe e a logo junto. */
.brand__logo {
  display: block;
  height: 38px;
  width: auto;
}

.topbar.is-stuck .brand__logo {
  height: 32px;
}

/* No rodapé há mais espaço vertical — a versão com a tagline pode crescer um
 * pouco mais e ela continua legível. */
.brand--footer {
  margin: 0;
}

.brand--footer .brand__logo {
  height: 44px;
}

/* A navegação some no telefone: os mesmos destinos estão no corpo da página, e
 * o botão de comprar é o que precisa ficar ao alcance do polegar. */
.topbar__nav {
  display: none;
}

.topbar__nav a {
  color: var(--ink);
  text-decoration: none;
  font-weight: 500;
}

.topbar__nav a:hover {
  color: var(--accent-text);
}

@media (min-width: 900px) {
  .topbar {
    min-height: 88px;
    padding: 8px 40px;
  }

  .topbar.is-stuck {
    min-height: 64px;
  }

  .brand__logo {
    height: 50px;
  }

  .topbar.is-stuck .brand__logo {
    height: 40px;
  }

  .topbar__nav {
    display: flex;
    gap: 32px;
  }
}

/* ---------------------------------------------------------------------------
 * Hero
 * ------------------------------------------------------------------------- */

.hero {
  display: grid;
  gap: 28px;
  max-width: 1200px;
  margin: 0 auto;
  padding: 24px var(--gutter) 48px;
}

.hero__say {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
}

.tag {
  padding: 7px 14px;
  border-radius: 999px;
  background: var(--tag-bg);
  /* `--accent-text`, porque aqui o destaque é texto. Já esteve com o antigo
   * `--accent-dark` (o rosa de hover de fundo) e dava 3,6:1 sobre a etiqueta no
   * tema escuro. Aquele token foi dividido justamente por causa deste tipo de
   * confusão e não existe mais. */
  color: var(--accent-text);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.hero__title {
  font-size: clamp(2.25rem, 11vw, 2.75rem);
  line-height: 1.04;
  letter-spacing: -0.02em;
}

.hero__lede,
.band__lede {
  color: var(--muted);
  font-size: 1.0625rem;
  /* Linha abaixo de 80 caracteres em qualquer largura. */
  max-width: 58ch;
}

.pricebox {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pricebox__line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
}

.pricebox__amount {
  font-family: var(--serif);
  font-size: clamp(2rem, 9vw, 2.5rem);
  font-weight: 600;
  line-height: 1;
}

/* O preço "de" é informação secundária: mesmo tom do texto de apoio, e o risco
 * fino para não competir com o preço que vale. */
.pricebox__compare {
  color: var(--muted);
  font-size: 1.0625rem;
  text-decoration-thickness: 1px;
}

.pricebox__unit,
.pricebox__terms {
  color: var(--muted);
  font-size: 0.9375rem;
}

.trust {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  width: 100%;
  color: var(--muted);
  font-size: 0.8125rem;
  font-weight: 500;
}

.trust li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
}

.trust svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* O palco do produto: círculo claro sobre rosa, com o desenho do pote no meio.
 * Vira fotografia sem mexer no layout, desde que a proporção se mantenha. */
/* No telefone a foto vem antes do texto, como na referência. A ordem do HTML
 * mantém o h1 primeiro, que é o que leitor de tela deve encontrar; a figura não
 * tem nada focável dentro, então trocar a posição visual não mexe na ordem de
 * tabulação. */
.shot {
  order: -1;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.shot__stage,
.offer__stage {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-lg);
  background: var(--stage);
  overflow: hidden;
}

/* O círculo suave por trás. Era o palco do ícone SVG (que flutuava pequeno,
 * 52% de largura, centralizado nele) — com a fotografia real cobrindo o palco
 * inteiro (regra abaixo), este círculo fica encoberto na maior parte do tempo.
 * Continua aqui como rede de segurança: se a foto falhar ao carregar, ou
 * enquanto ela ainda não chegou, é o círculo que aparece por trás do espaço
 * reservado, em vez de um retângulo vazio da cor do palco. */
.shot__stage::before,
.offer__stage::before {
  content: "";
  position: absolute;
  width: 72%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--stage-inner);
}

/* A foto atual (imagem-inicio-vitahair.jpg) é um print de story quase
 * quadrado, com texto colado nas quatro bordas (bullets à esquerda, etiquetas
 * em cima e embaixo) — diferente da foto de produto 3:4 que ela substituiu,
 * que só perdia uma tira fina das laterais com `cover`. Um `cover` num quadro
 * 16:11, 4:5 ou 5:6 corta esse texto. `contain` garante a foto inteira visível
 * em qualquer proporção de palco, ao custo de sobrar um pouco do fundo
 * (`--stage`/`--stage-inner`) nas bordas onde a proporção não bate. */
/* O palco do hero tem a proporção da própria foto (1179 × 1175, os mesmos
 * números de width/height do <img>). Com o 4:5 herdado acima — 5:6 no desktop —
 * a foto quase quadrada não alcançava a altura do palco, e o `contain` abaixo
 * deixava uma faixa de `--stage` em cima e outra embaixo. Na mesma proporção,
 * `contain` preenche o palco inteiro sem cortar nada. Trocar a foto é trocar
 * este número junto. O card de compra (`.offer__stage`) não muda. */
.shot__stage {
  aspect-ratio: 1179 / 1175;
}

.shot__jar,
.offer__jar {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: 50% 50%;
}

.shot__note {
  color: var(--muted);
  font-size: 0.8125rem;
  text-align: center;
}

@media (min-width: 900px) {
  .hero {
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 64px;
    padding: 64px 40px 80px;
  }

  .hero__title {
    font-size: clamp(2.75rem, 4.6vw, 4.25rem);
  }

  .hero__lede,
  .band__lede {
    font-size: 1.125rem;
  }

  .pricebox {
    padding: 20px 24px;
    border: var(--border-width) solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
  }

  /* Só o CTA do hero encolhe para o tamanho do texto. `--wide` continua
   * significando largura cheia no botão de enviar o formulário e no card de
   * compra, onde a coluna é estreita e o botão é o fim da leitura. */
  .hero__say .button--wide {
    width: auto;
    min-width: 260px;
  }

  .trust {
    display: flex;
    gap: 28px;
    font-size: 0.9375rem;
  }

  .trust li {
    flex-direction: row;
    text-align: left;
  }

  .shot {
    order: 0;
  }
}

/* ---------------------------------------------------------------------------
 * Imagem ao lado de conteúdo
 *
 * Um padrão só, reaproveitado onde uma foto de apoio entra ao lado de um bloco
 * de texto ou de cards: hoje, a foto do rótulo na Fórmula. Empilhado no
 * telefone (a foto primeiro, âncora visual antes do texto), lado a lado a
 * partir de 900px. A mesma ideia de grid que `.offer` já usa, só que genérica.
 * ------------------------------------------------------------------------- */

.split {
  display: grid;
  gap: 24px;
}

.split__figure {
  margin: 0;
}

.split__figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  object-fit: cover;
}

@media (min-width: 900px) {
  .split {
    grid-template-columns: minmax(200px, 300px) 1fr;
    gap: 40px;
    align-items: start;
  }

  .split__figure img {
    aspect-ratio: 3 / 4;
  }
}

/* ---------------------------------------------------------------------------
 * Fórmula
 * ------------------------------------------------------------------------- */

.band__head {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-bottom: 28px;
}

.actives {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.active {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 18px;
  border-radius: 16px;
  background: var(--bg);
}

.active__name {
  font-family: var(--serif);
  font-size: 1.375rem;
  color: var(--accent-text);
}

/* A lista de vitaminas, no card que agrupa as onze. Cor de conteúdo real (não
 * de placeholder): diferente de `.active__dose`, que é sempre o aviso de dado
 * que falta. */
.active__list {
  color: var(--ink);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.active__dose {
  color: var(--muted);
  font-size: 0.875rem;
  line-height: 1.45;
}

@media (min-width: 900px) {
  /* Respiro e invasão crescem juntos na tela larga. `.band` e `.band--overlapped`
   * leem os dois da raiz, então não há valor repetido por faixa de largura. */
  :root {
    --band-pad: 88px;
    --overlap: 110px;
  }

  .band__head {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: 48px;
    margin-bottom: 48px;
  }

  /* Dentro do `.split` da Fórmula, o cabeçalho divide a coluna de conteúdo com
   * a foto do rótulo ao lado — título e texto de apoio ficam empilhados, não
   * lado a lado, porque a coluna aqui é mais estreita que a faixa inteira. */
  .split .band__head {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
    margin-bottom: 24px;
  }

  .section-title {
    font-size: clamp(2rem, 3.4vw, 3.25rem);
  }

  /* Seis ativos: dois de três, não quatro de um jeito qualquer. */
  .actives {
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
  }

  .active {
    min-height: 160px;
    padding: 22px;
  }

  /* Menor que antes: os nomes reais ("Ácido Hialurônico", "Silício Orgânico")
   * são bem mais longos que o placeholder "[Ativo N]", e o card ficou mais
   * estreito — três colunas dentro da coluna de conteúdo do `.split`, não
   * quatro na largura cheia da faixa. */
  .active__name {
    font-size: 1.5rem;
  }

  .active__list {
    font-size: 1rem;
  }

  .active__dose {
    font-size: 0.9375rem;
  }
}

/* Tabela nutricional completa, logo abaixo dos ativos em destaque. */
.nutrition {
  margin-top: 32px;
  padding-top: 32px;
  border-top: var(--border-width) solid var(--line);
}

.nutrition__title {
  font-family: var(--serif);
  font-size: 1.375rem;
  color: var(--ink);
  margin-bottom: 8px;
}

.nutrition__servings {
  color: var(--muted);
  font-size: 0.9375rem;
  margin-bottom: 16px;
}

.nutrition__scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.nutrition__table {
  width: 100%;
  min-width: 360px;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.nutrition__table th,
.nutrition__table td {
  padding: 8px 12px;
  text-align: left;
  border-bottom: var(--border-width) solid var(--line);
  color: var(--ink);
}

.nutrition__table th {
  font-weight: 600;
  color: var(--muted);
}

.nutrition__table th:nth-child(2),
.nutrition__table th:nth-child(3),
.nutrition__table td:nth-child(2),
.nutrition__table td:nth-child(3) {
  text-align: right;
  white-space: nowrap;
}

.nutrition__footnote {
  margin-top: 12px;
  color: var(--muted);
  font-size: 0.8125rem;
  line-height: 1.5;
}

/* ---------------------------------------------------------------------------
 * Benefícios
 * ------------------------------------------------------------------------- */

.benefits {
  display: grid;
  gap: 12px;
}

.card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 24px;
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius);
}

.card__icon {
  width: 32px;
  height: 32px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.card h3 {
  font-size: 1.375rem;
}

.card p {
  color: var(--muted);
  font-size: 0.9375rem;
}

@media (min-width: 900px) {
  .benefits {
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
  }

  .card {
    gap: 16px;
    padding: 36px;
    border-radius: 24px;
  }

  .card__icon {
    width: 40px;
    height: 40px;
  }

  .card h3 {
    font-size: 1.75rem;
  }

  .card p {
    font-size: 1.0625rem;
  }
}

/* ---------------------------------------------------------------------------
 * Como usar
 * ------------------------------------------------------------------------- */

.steps {
  display: grid;
  gap: 0;
  margin-top: 28px;
}

.steps li {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 16px;
  align-items: start;
  padding: 20px 0;
  border-top: var(--border-width) solid var(--invert-line);
}

/* A trilha que se preenche, sobre a linha cinza do passo. Absoluta de
 * propósito: assim ela sai do grid e não desloca o número nem o texto. Anima em
 * scaleX, nunca em width. */
.steps__rail {
  position: absolute;
  top: -1px;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--accent-light);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.8s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.steps li.is-on .steps__rail {
  transform: scaleX(1);
}

.steps__num {
  transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1),
    color 0.5s ease, text-shadow 0.5s ease;
}

/* Sem JS não há `is-on`: os três passos já nascem acesos, que é o estado certo
 * de uma página sem efeito. Com JS, landing-fx.js apaga e acende um por um. */
.fx-on .steps__num {
  transform: scale(0.82);
  transform-origin: left center;
  color: var(--step-dim);
}

.fx-on .steps li.is-on .steps__num {
  transform: scale(1);
  color: var(--accent-light);
  text-shadow: 0 0 28px var(--glow-accent);
}

.steps__num {
  grid-row: span 2;
  font-family: var(--serif);
  font-size: 2.25rem;
  font-weight: 500;
  line-height: 1;
  color: var(--accent-light);
}

.steps h3 {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 1.125rem;
}

.steps p {
  color: var(--invert-muted);
  font-size: 0.9375rem;
}

/* Foto pequena, só no passo 1: a cápsula na palma da mão, ilustrando "uma
 * cápsula por dia" ao pé da letra.
 *
 * No telefone, `.steps li` é um grid de duas colunas (número | conteúdo) com
 * posicionamento automático: sem esta regra, o `<picture>` cairia sozinho na
 * coluna estreita do número (primeira célula livre, à esquerda), não na
 * coluna de texto. No desktop `.steps li` vira uma coluna só (mais abaixo
 * nesta folha), e aí a foto simplesmente empilha depois do parágrafo — não
 * precisa de regra própria lá. */
.steps li picture {
  grid-column: 2;
}

.steps__shot {
  display: block;
  width: 76px;
  height: auto;
  margin-top: 12px;
  border-radius: 12px;
  object-fit: cover;
}

/* Foto de apoio da seção inteira, depois da lista de passos: alguém usando o
 * produto no dia a dia. Contida e centralizada — não é uma segunda coluna,
 * porque a lista de passos já ocupa a largura toda da faixa em telas largas
 * (três passos lado a lado) e dividir isso ao meio apertaria demais cada um. */
.howto__media {
  margin: 32px auto 0;
  max-width: 360px;
}

/* A foto é retrato bem alto (675×1200); a proporção fixa corta o excesso de
 * mesa e de chão e mantém o pote, a cápsula e o copo no quadro. */
.howto__media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius);
  object-fit: cover;
  object-position: 50% 42%;
}

@media (min-width: 900px) {
  .steps {
    grid-template-columns: repeat(3, 1fr);
    gap: 48px;
    margin-top: 48px;
  }

  .steps li {
    grid-template-columns: 1fr;
    row-gap: 12px;
    padding: 28px 0 0;
  }

  .steps__num {
    grid-row: auto;
    font-size: 3.5rem;
  }

  .steps h3 {
    font-size: 1.375rem;
  }

  .steps p {
    font-size: 1.0625rem;
  }

  .steps__shot {
    width: 96px;
  }

  .howto__media {
    max-width: 420px;
    margin-top: 56px;
  }
}

/* ---------------------------------------------------------------------------
 * Card de compra
 * ------------------------------------------------------------------------- */

/* O card sobe e invade a faixa escura de cima, para não ficar preso dentro da
 * sua própria seção. A faixa de cima não recorta o transbordo, então basta a
 * margem negativa e um z-index acima dela. */
.band--overlap {
  padding-top: 0;
}

.offer {
  position: relative;
  z-index: 2;
  margin-top: calc(-1 * var(--overlap));
  display: grid;
  gap: 20px;
  padding: 24px;
  border-radius: var(--radius-lg);
  background: var(--invert-bg);
  color: var(--invert-ink);
  box-shadow: 0 40px 80px -40px var(--shadow-strong);
}

.offer__stage {
  aspect-ratio: 16 / 11;
}

.offer__say {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.offer__eyebrow {
  color: var(--invert-muted);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.offer__title {
  font-size: clamp(1.75rem, 8vw, 2rem);
}

/* O card de compra é faixa invertida: o texto de apoio lá é --invert-muted. */
.offer__compare {
  display: block;
  color: var(--invert-muted);
  font-size: 1.0625rem;
  text-decoration-thickness: 1px;
}

.offer__price {
  font-family: var(--serif);
  font-size: clamp(2.25rem, 11vw, 2.75rem);
  font-weight: 600;
  line-height: 1;
}

.offer__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 0.9375rem;
  color: var(--invert-ink);
}

.offer__list li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px;
  align-items: start;
}

.offer__list li::before {
  content: "";
  width: 7px;
  height: 7px;
  margin-top: 0.55em;
  border-radius: 50%;
  background: var(--accent-light);
}

@media (min-width: 900px) {
  .offer {
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 56px;
    max-width: 1000px;
    margin: calc(-1 * var(--overlap)) auto 0;
    padding: 56px;
    border-radius: 32px;
  }

  .offer__stage {
    aspect-ratio: 1;
    border-radius: 24px;
  }

  .offer__say {
    gap: 20px;
  }

  .offer__title {
    font-size: 2.75rem;
  }

  .offer__price {
    font-size: 3.75rem;
  }

  .offer__list {
    font-size: 1rem;
  }
}

/* ---------------------------------------------------------------------------
 * Peças do checkout
 *
 * Painéis, campos, opções de frete e de pagamento, resumo e avisos. Só a página
 * /checkout/ usa isto — a landing não tem formulário nenhum. As regras de
 * enquadramento dela (header, etapas, coluna do resumo, rodapé curto) estão mais
 * abaixo, na seção "PÁGINA DO CHECKOUT".
 *
 * Os ids e as classes daqui para baixo são contrato com app.js e card-brick.js.
 * Estilo muda; nome, não.
 * ------------------------------------------------------------------------- */

.panels {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.panel {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.panel:focus {
  outline: none;
}

.panel form {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.panel__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

/* Campos ------------------------------------------------------------------ */

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.field label {
  font-size: 0.9375rem;
  font-weight: 600;
}

.field__optional {
  font-weight: 400;
  color: var(--muted);
}

.field input {
  min-height: var(--touch);
  padding: 10px 14px;
  border: var(--border-width) solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
}

.field input:hover {
  border-color: var(--accent-light);
}

.field input:focus-visible {
  border-color: var(--accent);
  outline-offset: 0;
}

.field__hint {
  color: var(--muted);
  font-size: 0.8125rem;
  max-width: 52ch;
}

.delivery,
.methods {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin: 0;
  padding: 20px;
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius);
}

.delivery legend,
.methods legend {
  padding: 0 8px;
  margin-left: -8px;
  font-family: var(--serif);
  font-size: 1.25rem;
  font-weight: 600;
}

.address-grid {
  display: grid;
  gap: 14px;
}

@media (min-width: 560px) {
  .address-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .field--grow {
    grid-column: 1 / -1;
  }
}

/* Opções de frete e de pagamento ------------------------------------------
 *
 * `.method` serve às duas: as de pagamento vêm no HTML, as de frete são criadas
 * por app.js (renderShippingOptions) com esta mesma estrutura — label.method >
 * input[radio] + span.method__text > span.method__note. */

.shipping-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.shipping-options__label {
  font-size: 0.9375rem;
  font-weight: 600;
}

.method {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
  align-items: start;
  min-height: var(--touch);
  padding: 14px;
  border: var(--border-width) solid var(--line);
  border-radius: 14px;
  background: var(--surface);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.method:hover {
  border-color: var(--accent-light);
}

.method:has(input:checked) {
  border-color: var(--accent);
  background: var(--method-on-bg);
}

.method:has(input:focus-visible) {
  outline: var(--focus-width) solid var(--accent-text);
  outline-offset: 2px;
}

.method input {
  width: 20px;
  height: 20px;
  margin: 2px 0 0;
  accent-color: var(--accent);
}

.method__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-weight: 600;
}

.method__note {
  color: var(--muted);
  font-size: 0.875rem;
  font-weight: 400;
}

/* Resumo ----------------------------------------------------------------- */

.summary {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 18px 20px;
  border-radius: var(--radius);
  background: var(--bg);
}

.summary__row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  font-size: 0.9375rem;
  color: var(--muted);
}

.summary__row--total {
  padding-top: 10px;
  border-top: var(--border-width) solid var(--line);
  color: var(--ink);
  font-weight: 700;
  font-size: 1.0625rem;
}

/* O desconto é a única linha do resumo que anda para baixo, e por isso é a
 * única com cor própria: sem ela, "-R$ 8,99" no meio de valores positivos é um
 * número que se lê errado de relance. --accent-text porque é destaque em forma
 * de texto — passa 4.5:1 nos três temas, o --accent de botão não passaria. */
.summary__row--discount {
  color: var(--accent-text);
  font-weight: 600;
}

/* Quantidade (passo 17) ----------------------------------------------------
 *
 * Herda rótulo de .field; o que falta é a linha com os dois botões de passo e
 * o campo numérico entre eles, e o selo do desconto progressivo logo abaixo. */
.qty {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.qty label {
  font-size: 0.9375rem;
  font-weight: 600;
}

.qty__controls {
  display: flex;
  align-items: stretch;
  gap: 8px;
}

.qty__controls button {
  flex: none;
  width: var(--touch);
  min-height: var(--touch);
  border: var(--border-width) solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
}

.qty__controls button:hover:not(:disabled) {
  border-color: var(--accent-light);
}

.qty__controls button:disabled {
  color: var(--muted);
  cursor: not-allowed;
}

.qty__controls input {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  min-height: var(--touch);
  padding: 10px 14px;
  border: var(--border-width) solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  text-align: center;
  /* As setas nativas duplicariam os botões de + e - ao lado. */
  -moz-appearance: textfield;
}

.qty__controls input::-webkit-outer-spin-button,
.qty__controls input::-webkit-inner-spin-button {
  margin: 0;
  -webkit-appearance: none;
}

.qty__controls button:focus-visible,
.qty__controls input:focus-visible {
  border-color: var(--accent);
  outline-offset: 0;
}

.qty__badge {
  color: var(--accent-text);
  font-size: 0.8125rem;
  font-weight: 600;
}

/* Cupom ------------------------------------------------------------------
 *
 * Herda rótulo e campo de .field. O que falta é a linha: o campo e o botão
 * dividem a largura, porque o botão é a resposta ao campo, não uma ação
 * separada. */
.coupon__row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}

.coupon__row input {
  flex: 1 1 auto;
  min-width: 0;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Não encolhe junto com o campo: "Aplicar" e "Remover" têm larguras
 * diferentes, e um botão que muda de tamanho ao trocar de rótulo empurra o
 * campo do lado. */
.coupon__row .button {
  flex: none;
  min-height: var(--touch);
  padding-inline: 18px;
}

/* Aplicado, o código deixa de ser editável: o que importa dali em diante é o
 * desconto, que já está no resumo. */
.coupon[data-applied="true"] .coupon__row input {
  background: var(--bg-soft);
  color: var(--muted);
}

.coupon #coupon-status[data-tone="ok"] {
  color: var(--accent-text);
  font-weight: 600;
}

.coupon #coupon-status[data-tone="warn"] {
  color: var(--warn-ink);
  font-weight: 600;
}

/* Avisos ----------------------------------------------------------------- */

.notice {
  padding: 12px 16px;
  border-radius: 14px;
  border-left: 4px solid var(--line);
  background: var(--bg);
  font-size: 0.9375rem;
}

.notice[data-tone="ok"] {
  border-left-color: var(--accent);
  background: var(--bg-soft);
}

.notice[data-tone="warn"] {
  border-left-color: var(--warn-edge);
  background: var(--warn-bg);
  color: var(--warn-ink);
  font-weight: 500;
}

/* Pix -------------------------------------------------------------------- */

.panel--pix h3,
.panel--card h3,
.panel--outcome h3 {
  font-size: 1.5rem;
}

/* O QR do Pix é a única coisa da folha que NÃO acompanha o tema.
 *
 * Fundo branco e margem branca, nos três temas, porque leitor de QR espera
 * módulos escuros sobre claro e precisa da zona de silêncio ao redor. Num tema
 * escuro o PNG do Mercado Pago ficaria sobre #0f0b0e, encostado na borda, e há
 * aplicativo de banco que simplesmente não lê isso. Branco literal de propósito:
 * é requisito do formato, não decisão de design, e não existe tema em que ele
 * possa mudar.
 *
 * `padding` é a zona de silêncio; `background-clip: border-box` garante que ela
 * seja branca até a borda. */
.pix__qr {
  width: 100%;
  max-width: 260px;
  align-self: center;
  padding: 12px;
  border: var(--border-width) solid var(--line);
  border-radius: 16px;
  background: #ffffff;
  background-clip: border-box;
}

.pix__clock {
  color: var(--muted);
  font-size: 0.9375rem;
  text-align: center;
}

.pix__clock time {
  font-family: var(--serif);
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

#pix-code {
  width: 100%;
  padding: 12px 14px;
  border: var(--border-width) solid var(--line);
  border-radius: 12px;
  background: var(--bg);
  color: var(--ink);
  font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
  font-size: 0.8125rem;
  resize: vertical;
}

/* O Brick monta um iframe aqui. O container precisa ter caixa de layout antes
 * da montagem — ver a guarda em card-brick.js. */
#card-brick {
  min-height: 320px;
}

/* Desfecho --------------------------------------------------------------- */

.panel--outcome {
  padding: 24px;
  border-radius: var(--radius);
  border-left: 4px solid var(--line);
  background: var(--bg);
  align-items: flex-start;
}

.panel--outcome[data-tone="ok"] {
  border-left-color: var(--accent);
  background: var(--bg-soft);
}

.panel--outcome[data-tone="warn"] {
  border-left-color: var(--warn-edge);
  background: var(--warn-bg);
}

.panel--outcome p {
  color: var(--muted);
  max-width: 54ch;
}

/* O enquadramento em duas colunas mudou de lugar: agora é `.wrap--co`, na seção
 * "PÁGINA DO CHECKOUT". `.checkout`, `.wrap--checkout` e `.checkout__pitch`
 * saíram junto com a seção de pagamento que morava na landing. */

/* ---------------------------------------------------------------------------
 * Depoimentos
 * ------------------------------------------------------------------------- */

.voices {
  display: grid;
  gap: 12px;
  margin-top: 28px;
}

.voices figure {
  display: flex;
  flex-direction: column;
  gap: 14px;
  height: 100%;
  margin: 0;
  padding: 24px;
  border-radius: var(--radius);
  background: var(--surface);
}

.voices blockquote {
  margin: 0;
  font-family: var(--serif);
  font-size: 1.1875rem;
  line-height: 1.45;
}

.voices figcaption {
  color: var(--muted);
  font-size: 0.875rem;
  font-weight: 600;
  margin-top: auto;
}

.voices__more {
  margin-top: 20px;
  font-weight: 600;
}

/* Uma coluna por depoimento, quantos houver: dois dividem a largura ao meio, um
 * terceiro real entra como mais um <li> e a grade passa a três sozinha. Com
 * `repeat(3, 1fr)` fixo, dois depoimentos deixavam um terço vazio à direita. */
@media (min-width: 900px) {
  .voices {
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 24px;
    margin-top: 48px;
  }

  .voices figure {
    padding: 36px;
    border-radius: 24px;
  }

  .voices blockquote {
    font-size: 1.375rem;
  }
}

/* ---------------------------------------------------------------------------
 * FAQ
 * ------------------------------------------------------------------------- */

.wrap--faq {
  display: grid;
  gap: 28px;
}

.faq__intro {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}

.faq__intro p {
  color: var(--muted);
}

.faq details {
  border-top: var(--border-width) solid var(--faq-line);
}

.faq details:last-child {
  border-bottom: var(--border-width) solid var(--faq-line);
}

.faq summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  min-height: var(--touch);
  padding: 16px 0;
  font-size: 1.0625rem;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.faq summary::-webkit-details-marker {
  display: none;
}

/* O sinal de abrir gira ao abrir — movimento como resposta a uma ação. */
.faq summary::after {
  content: "";
  flex-shrink: 0;
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: transform 0.18s ease;
}

.faq details[open] summary::after {
  transform: rotate(-135deg);
}

.faq details p {
  padding: 0 0 18px;
  color: var(--muted);
  max-width: 62ch;
}

@media (min-width: 900px) {
  .wrap--faq {
    grid-template-columns: 4fr 7fr;
    gap: 64px;
    align-items: start;
  }

  .faq summary {
    font-size: 1.25rem;
    padding: 22px 0;
  }
}

/* ---------------------------------------------------------------------------
 * Faixa final
 * ------------------------------------------------------------------------- */

.finale {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 32px 24px;
  border-radius: var(--radius-lg);
  background: var(--accent);
  color: var(--accent-on);
}

.finale__title {
  font-size: clamp(1.75rem, 8vw, 2rem);
}

.finale__note {
  margin-top: 12px;
  color: var(--on-accent-soft);
  font-size: 0.9375rem;
}

@media (min-width: 900px) {
  .finale {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 48px;
    padding: 72px;
    border-radius: 36px;
  }

  .finale__title {
    font-size: clamp(2rem, 3.6vw, 3.5rem);
    max-width: 44ch;
  }

  .finale__note {
    font-size: 1.125rem;
  }
}

/* ---------------------------------------------------------------------------
 * Rodapé
 * ------------------------------------------------------------------------- */

.foot {
  padding: 40px 0;
  background: var(--invert-bg);
  color: var(--invert-muted);
  font-size: 0.875rem;
}

.foot__grid {
  display: grid;
  gap: 24px;
}

.foot h2 {
  margin-bottom: 8px;
  font-family: var(--sans);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--invert-ink);
}

.foot ul {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.foot a {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  color: var(--invert-muted);
}

.foot a:hover {
  color: var(--invert-ink);
}

.foot__brand p + p {
  margin-top: 8px;
}

.foot__legal {
  margin-top: 28px;
  padding-top: 20px;
  border-top: var(--border-width) solid var(--invert-line-soft);
  font-size: 0.8125rem;
  line-height: 1.6;
  max-width: 78ch;
}

@media (min-width: 900px) {
  .foot {
    padding: 72px 0;
  }

  .foot__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 40px;
  }
}

/* ===========================================================================
 * CONTROLES DE TEMA E IDIOMA
 *
 * Os mesmos nas duas páginas, no header. No telefone eles passam para uma segunda
 * linha do header (`flex-wrap`), porque marca + tema + idioma + botão de comprar
 * não cabem em 360px sem apertar a área de toque de nenhum deles.
 * ======================================================================== */

.prefs {
  display: flex;
  align-items: center;
  gap: 8px;
}

.prefs__theme {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: var(--touch);
  padding: 8px 12px;
  border: var(--border-width) solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
}

.prefs__theme:hover {
  border-color: var(--accent-text);
  color: var(--accent-text);
}

.prefs__icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}

/* O nome do tema só aparece onde há espaço; o ícone e o `aria-label` carregam a
 * informação no telefone. */
.prefs__theme-text {
  display: none;
}

.prefs__lang {
  display: flex;
  align-items: center;
  border: var(--border-width) solid var(--line);
  border-radius: 999px;
  overflow: hidden;
}

.prefs__lang button {
  min-width: 40px;
  min-height: var(--touch);
  padding: 8px 10px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
}

.prefs__lang button:hover {
  color: var(--accent-text);
}

/* O idioma ativo, marcado por `aria-pressed` — o estilo pendura no estado real,
 * não numa classe paralela que poderia divergir dele. */
.prefs__lang button[aria-pressed="true"] {
  background: var(--accent);
  color: var(--accent-on);
}

@media (max-width: 559px) {
  .topbar {
    flex-wrap: wrap;
  }

  /* Segunda linha do header, alinhada à direita. */
  .topbar .prefs {
    order: 3;
    width: 100%;
    justify-content: flex-end;
  }
}

@media (min-width: 900px) {
  .prefs__theme-text {
    display: inline;
  }
}

/* Aviso de entrega só no Brasil — visível apenas em inglês e espanhol ---------
 *
 * i18n.js revela ou esconde pelo atributo `data-i18n-intl-only`. Em português
 * seria ruído; nos outros dois é o que evita uma compra que não pode ser
 * concluída. */

.offer__notice,
.co__notice {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  border-radius: 14px;
  border-left: 4px solid var(--warn-edge);
  background: var(--warn-bg);
  color: var(--warn-ink);
  font-size: 0.875rem;
}

.co__notice {
  margin-bottom: 20px;
}

/* Sobre o card escuro do card de compra o aviso precisa do próprio contraste. */
.offer__notice {
  background: var(--invert-ink);
  color: var(--invert-bg);
  border-left-color: var(--accent);
}

/* Aviso legal em português, repetido em outros idiomas --------------------- */

.foot__legal--pt,
.cofoot__legal--pt {
  margin-top: 12px;
  padding-top: 0;
  border-top: 0;
  opacity: 0.85;
}

.foot__legal-note {
  display: block;
  font-weight: 600;
  margin-bottom: 4px;
}

/* ===========================================================================
 * PÁGINA DO CHECKOUT (/checkout/)
 *
 * Mesma folha, mesmas fontes, mesmas variáveis da landing — é a mesma marca, e
 * uma página de pagamento que parece de outro site é página que perde venda.
 *
 * O que muda é o que NÃO tem: nenhum efeito. A única animação daqui é opacidade
 * ao trocar de etapa e de painel, no fim desta seção. Nada de parallax, tilt,
 * ou revelação ao rolar — a página nem carrega o landing-fx.js.
 * ======================================================================== */

.page-co {
  background: var(--bg);
}

/* Header curto: marca à esquerda, selo à direita. Sem navegação. */
.cobar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 64px;
  padding: 8px var(--gutter);
  border-bottom: var(--border-width) solid var(--line);
  background: var(--surface);
}

.cobar__seal {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 0.875rem;
  font-weight: 600;
}

/* Mesma solução do header da landing: no telefone os controles de tema e idioma
 * passam para uma segunda linha, em vez de comprimir a área de toque de todos. */
@media (max-width: 559px) {
  .cobar {
    flex-wrap: wrap;
  }

  .cobar .prefs {
    order: 3;
    width: 100%;
    justify-content: flex-end;
  }
}

.cobar__seal svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.co {
  padding: 28px 0 56px;
}

.wrap--co {
  display: grid;
  gap: 24px;
  max-width: 1080px;
}

.co__title {
  font-size: clamp(1.75rem, 7vw, 2.25rem);
  margin-bottom: 20px;
}

.co__safety {
  color: var(--muted);
  font-size: 0.8125rem;
}

/* Indicador das etapas ---------------------------------------------------
 *
 * Diz onde a pessoa está e quantas faltam. A etapa 2 desaparece quando o produto
 * não exige frete: checkout-steps.js esconde o item, e o `hidden` global cuida do
 * resto. */

.stepbar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 24px;
  padding-bottom: 20px;
  border-bottom: var(--border-width) solid var(--line);
}

.stepbar li {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 0.8125rem;
  font-weight: 600;
}

/* O traço entre os itens. Só entre, nunca antes do primeiro. */
.stepbar li + li::before {
  content: "";
  width: 12px;
  height: 1px;
  background: var(--line);
}

@media (min-width: 560px) {
  .stepbar li + li::before {
    width: 28px;
  }
}

.stepbar__num {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border: var(--border-width) solid var(--line);
  border-radius: 50%;
  background: var(--surface);
  font-variant-numeric: tabular-nums;
}

/* A etapa atual: o número acende. `aria-current` é a fonte da verdade, então o
 * estilo pendura nele em vez de numa classe paralela. */
.stepbar li[aria-current="step"] {
  color: var(--ink);
}

.stepbar li[aria-current="step"] .stepbar__num {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-on);
}

.stepbar li[data-done] .stepbar__num {
  border-color: var(--accent-text);
  color: var(--accent-text);
}

/* No telefone só a etapa atual mostra o rótulo: três nomes lado a lado não
 * cabem em 360px. Os números continuam todos visíveis. */
.stepbar__label {
  display: none;
}

.stepbar li[aria-current="step"] .stepbar__label {
  display: inline;
}

@media (min-width: 560px) {
  .stepbar__label {
    display: inline;
  }
}

/* Etapas ---------------------------------------------------------------- */

.step {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin: 0;
  padding: 0;
  border: 0;
}

.step__title {
  font-size: 1.5rem;
}

/* O título recebe foco ao entrar na etapa, mas não é um controle: sem anel
 * permanente, só o anel de foco normal quando o teclado chega nele. */
.step__title:focus {
  outline: none;
}

.step__title:focus-visible {
  outline: var(--focus-width) solid var(--accent-text);
  outline-offset: 4px;
}

.step__nav {
  display: flex;
  flex-wrap: wrap-reverse;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
}

.step__nav .button--loud {
  flex: 1 1 200px;
}

/* Erro da etapa que a validação do navegador não cobre — hoje, a escolha do
 * frete, cujos rádios são criados por app.js e não têm `required`. */
.step__error {
  padding: 12px 16px;
  border-radius: 14px;
  border-left: 4px solid var(--warn-edge);
  background: var(--warn-bg);
  color: var(--warn-ink);
  font-size: 0.9375rem;
  font-weight: 500;
}

/* Resumo do pedido ------------------------------------------------------
 *
 * <details> no telefone, recolhível, com o total à mostra mesmo fechado. A
 * partir de 900px vira coluna fixa e o botão de recolher desaparece —
 * checkout-steps.js garante que ele fique aberto nessa largura. */

.ordersum {
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.ordersum__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: var(--touch);
  padding: 14px 18px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.ordersum__toggle::-webkit-details-marker {
  display: none;
}

.ordersum__toggle strong {
  font-family: var(--serif);
  font-size: 1.25rem;
}

.ordersum__toggle::after {
  content: "";
  flex-shrink: 0;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
}

.ordersum[open] .ordersum__toggle::after {
  transform: rotate(-135deg);
}

.ordersum__body {
  padding: 0 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.ordersum__product {
  color: var(--muted);
  font-weight: 600;
  font-size: 0.9375rem;
}

.ordersum__note {
  color: var(--muted);
  font-size: 0.8125rem;
}

@media (min-width: 900px) {
  .co {
    padding: 48px 0 88px;
  }

  .wrap--co {
    grid-template-columns: 7fr 5fr;
    gap: 56px;
    align-items: start;
  }

  .co__aside {
    position: sticky;
    top: 24px;
  }

  /* Coluna fixa: não há o que recolher, e o cabeçalho volta a ser só um
   * título. */
  .ordersum__toggle {
    cursor: default;
    padding-bottom: 8px;
  }

  .ordersum__toggle::after {
    display: none;
  }

  .ordersum__toggle strong {
    display: none;
  }
}

/* Rodapé curto ---------------------------------------------------------- */

.cofoot {
  padding: 28px 0;
  border-top: var(--border-width) solid var(--line);
  background: var(--surface);
  color: var(--muted);
  font-size: 0.875rem;
}

.cofoot__line {
  margin-bottom: 8px;
}

.cofoot__line a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 32px;
  font-weight: 600;
}

.cofoot__line svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.cofoot__legal {
  margin-top: 16px;
  padding-top: 16px;
  border-top: var(--border-width) solid var(--line);
  font-size: 0.75rem;
  line-height: 1.6;
  max-width: 78ch;
}

/* A única animação do checkout ------------------------------------------
 *
 * Opacidade, e nada mais: sem deslocamento, sem escala, sem atraso. O container
 * do Payment Brick precisa ter dimensão no instante em que app.js manda montar,
 * e opacidade não mexe em caixa de layout. Quem está digitando CPF não precisa de
 * espetáculo. */

@keyframes co-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.step:not([hidden]),
.page-co .panel:not([hidden]) {
  animation: co-fade-in 0.2s ease both;
}

/* ===========================================================================
 * EFEITOS DA LANDING
 *
 * Tudo daqui para baixo é acabamento: profundidade, revelação, parallax e
 * microinteração. Duas coisas valem para o bloco inteiro.
 *
 * Primeira: nada aqui alcança o checkout. Os seletores de revelação e de tilt
 * dependem de atributos que landing-fx.js só distribui fora de #checkout, e o
 * único efeito dentro dele é a transição entre painéis, no fim desta seção.
 *
 * Segunda: o estado sem JS é o estado bom. As regras que escondem conteúdo de
 * véspera moram todas sob `.fx-on`, que só existe quando o JS está vivo — e que
 * o próprio <head> remove se landing-fx.js não confirmar que chegou.
 * ======================================================================== */

/* Camadas de fundo -------------------------------------------------------- */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: clip;
}

.backdrop__blob {
  position: absolute;
  display: block;
  border-radius: 50%;
  /* Borrão grande é caro de repintar. Como a camada é `fixed` e só recebe
   * translate, o navegador desenha o desfoque uma vez e depois só move a
   * textura. */
  filter: blur(70px);
  will-change: transform;
}

.backdrop__blob--1 {
  top: -8vh;
  right: -14vw;
  width: 62vw;
  height: 62vw;
  background: var(--blob-1);
}

.backdrop__blob--2 {
  top: 48vh;
  left: -22vw;
  width: 54vw;
  height: 54vw;
  background: var(--blob-2);
}

.backdrop__blob--3 {
  top: 120vh;
  right: -10vw;
  width: 40vw;
  height: 40vw;
  background: var(--blob-3);
}

/* Divisórias em onda ------------------------------------------------------ */

/* A onda sobe `--wave-height` acima da própria seção, por cima do que vier
 * antes. A faixa corrida usa o mesmo número como margem de baixo, para a onda da
 * seção seguinte cair na folga e não em cima do texto. */
:root {
  --wave-height: 34px;
}

@media (min-width: 900px) {
  :root {
    --wave-height: 56px;
  }
}

.wave {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: var(--wave-height);
  line-height: 0;
  pointer-events: none;
}

.wave svg {
  display: block;
  width: 100%;
  height: 100%;
}

.wave path {
  fill: var(--wave-fill, var(--bg));
}

/* Revelação ao rolar -----------------------------------------------------
 *
 * Só `opacity` e `transform`. O atraso em cascata vem de duas variáveis que
 * landing-fx.js escreve: `--i` (posição no grupo) e `--stagger` (o passo). */

.fx-on [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 20px, 0);
}

.fx-on [data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition: opacity 0.6s ease, transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
  transition-delay: calc(var(--i, 0) * var(--stagger, 0ms));
}

/* Quem se divide em palavras não sobe como bloco: senão o movimento se soma ao
 * de cada palavra e o título entra duas vezes. A entrada fica só nas palavras. */
.fx-on [data-reveal][data-split] {
  opacity: 1;
  transform: none;
}

/* Palavra por palavra no h1. O <span> externo recorta, o interno sobe de baixo.
 * O par padding/margem dá folga para as descidas do "p" e do "ç" não serem
 * cortadas pelo recorte, sem mudar a altura da linha. */
.word {
  display: inline-block;
  overflow: clip;
  vertical-align: bottom;
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
}

.fx-on .word__in {
  display: inline-block;
  transform: translate3d(0, 100%, 0);
  opacity: 0;
}

.fx-on [data-reveal].is-in .word__in {
  transform: none;
  opacity: 1;
  transition: opacity 0.5s ease, transform 0.66s cubic-bezier(0.22, 0.61, 0.36, 1);
  transition-delay: calc(var(--w, 0) * 55ms);
}

/* Etiquetas de vidro fosco ----------------------------------------------- */

.chip {
  position: absolute;
  z-index: 2;
  padding: 9px 14px;
  border: var(--border-width) solid var(--glass-border);
  border-radius: 14px;
  /* Sem `backdrop-filter` não há vidro: o fundo precisa ser opaco o bastante para
   * o texto continuar legível sobre o palco rosa. O bloco @supports abaixo troca
   * por um fundo mais fino, aí sim com desfoque atrás. No alto contraste os dois
   * valores são cor cheia. */
  background: var(--glass-bg-fallback);
  color: var(--ink);
  font-size: 0.8125rem;
  font-weight: 600;
  box-shadow: 0 10px 30px -18px var(--shadow-soft);
}

@supports (backdrop-filter: blur(1px)) {
  .chip {
    background: var(--glass-bg);
    backdrop-filter: var(--glass-blur);
  }
}

/* A etiqueta não pode cobrir o texto da foto: a lista de benefícios ocupa o
 * terço esquerdo, da borda de cima até a metade. No telefone a frase é larga
 * para a foto e, no canto de cima, encostava em "FORTALECE" — em inglês, cobria
 * o fim da palavra. Embaixo à direita só há o console do carro. No desktop a
 * foto é larga o bastante para o canto de cima, logo abaixo. */
.chip--offer {
  right: 14px;
  bottom: 14px;
  max-width: calc(100% - 28px);
}

@keyframes chip-float {
  from {
    transform: translate3d(0, -5px, 0);
  }
  to {
    transform: translate3d(0, 5px, 0);
  }
}

.fx-on .chip {
  animation: chip-float 5.5s ease-in-out infinite alternate;
}

@media (min-width: 900px) {
  .chip {
    padding: 12px 18px;
    font-size: 0.9375rem;
    border-radius: 16px;
  }

  .chip--offer {
    top: 24px;
    right: 24px;
    bottom: auto;
    max-width: calc(100% - 48px);
  }
}

/* Faixa infinita --------------------------------------------------------- */

/* A faixa é horizontal e do tamanho da própria caixa, de propósito. Ela já foi
 * uma barra girada 2,2° e maior que a caixa, e a onda de #formula (`.wave`, que
 * sobe por cima da seção de cima) passava por cima da metade de baixo do texto:
 * a cliente via as frases tortas e cortadas. Agora nada é girado, e a margem de
 * baixo é a altura da onda, então ela cai na folga entre as duas.
 *
 * `overflow: clip` recorta a trilha, que tem milhares de pixels: sem isso ela
 * criaria rolagem horizontal, e resolver com `overflow-x` no <body> quebraria o
 * header sticky e poderia recortar o fundo `fixed` do parallax. */
.marquee {
  position: relative;
  height: 58px;
  margin-top: 28px;
  margin-bottom: var(--wave-height);
  overflow: clip;
}

.marquee__bar {
  display: flex;
  align-items: center;
  height: 100%;
  background: var(--invert-bg);
  color: var(--invert-ink);
}

/* `flex: none` é o que faz a faixa rodar em sequência em vez de empilhada.
 *
 * A trilha é item flex do `.marquee__bar`. Item flex encolhe por padrão
 * (`flex-shrink: 1`), então a trilha — que tem milhares de pixels de conteúdo —
 * era comprimida até a largura da barra. Os dois grupos, também itens flex, eram
 * comprimidos junto; com `white-space: nowrap` o texto não podia quebrar, então ele
 * transbordava a própria caixa e as duas cópias do laço apareciam UMA SOBRE A
 * OUTRA. De quebra, o `-50%` da animação passava a ser metade de uma largura
 * encolhida, que não é mais o tamanho de um grupo, e o laço perdia a emenda. */
.marquee__track {
  display: flex;
  flex: none;
  width: max-content;
}

.marquee__group {
  display: flex;
  flex: none;
  /* Cada cópia tem de ser no mínimo tão larga quanto a tela. A animação desloca
   * a trilha em 50% (= um grupo); se um grupo for mais estreito que a faixa
   * visível, o fim do laço deixa um vazio à direita. `100vw` garante a cobertura
   * em qualquer largura, e os dois grupos recebem o mesmo mínimo, então continuam
   * com largura idêntica — que é a condição para a emenda ser invisível. */
  min-width: 100vw;
  justify-content: space-around;
  align-items: center;
  gap: 20px;
  padding-right: 20px;
  font-family: var(--serif);
  font-size: 1.125rem;
  font-weight: 500;
  white-space: nowrap;
}

/* Os pontos separadores. Eram selecionados por `span[aria-hidden]`, e a reescrita
 * para i18n tirou o `aria-hidden` de dentro deles — a faixa inteira já é
 * aria-hidden, então repetir era redundante, mas o seletor deixou de casar e os
 * pontos perderam a cor. Agora a classe é explícita. */
.marquee__sep {
  color: var(--accent-light);
}

@keyframes marquee-run {
  to {
    /* Dois grupos idênticos: a -50% o segundo está exatamente onde o primeiro
     * começou, e o laço não tem costura visível. */
    transform: translate3d(-50%, 0, 0);
  }
}

/* Sem `.fx-on` no seletor: a faixa é CSS puro e não precisa de landing-fx.js
 * para rodar. Antes ela só andava com a classe, e o script do <head> tira a
 * classe se landing-fx.js não confirmar que chegou em 2 s, e aí a faixa ficaria
 * parada no começo, sem voltar a andar quando o script chegasse. */
.marquee__track {
  animation: marquee-run 32s linear infinite;
}

@media (min-width: 900px) {
  .marquee {
    height: 76px;
    margin-top: 40px;
  }

  .marquee__group {
    gap: 32px;
    padding-right: 32px;
    font-size: 1.5rem;
  }
}

/* Palavra gigante ao fundo ----------------------------------------------- */

/* `z-index: -1` põe a palavra acima do fundo da faixa e abaixo do conteúdo, sem
 * precisar mexer no z-index de nada que se lê. Funciona porque `.band--dark`
 * isola o empilhamento. */
.ghost {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: clip;
  pointer-events: none;
}

.ghost__word {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  transform: translate3d(0, -50%, 0);
  text-align: center;
  font-family: var(--serif);
  font-size: clamp(9rem, 34vw, 26rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.02em;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--ghost-stroke);
  user-select: none;
}

/* Tilt e reflexo dos cards ----------------------------------------------- */

/* `isolation: isolate` para o reflexo em `z-index: -1` ficar acima do fundo do
 * card e abaixo do texto. Sem `transform-style: preserve-3d` de propósito: a
 * perspectiva vai na própria função `perspective()` da transformação, e num
 * contexto 3D o `z-index` do reflexo deixaria de valer — ele subiria para cima
 * das palavras. */
.card,
.active {
  position: relative;
  isolation: isolate;
  transition: transform 0.4s cubic-bezier(0.22, 0.61, 0.36, 1),
    box-shadow 0.4s ease;
}

.card.is-tilting,
.active.is-tilting {
  /* Perspectiva na própria transformação: não precisa de `perspective` no pai,
   * que interferiria no empilhamento dos cards. */
  transform: perspective(900px) rotateX(calc(var(--ty, 0) * -5deg))
    rotateY(calc(var(--tx, 0) * 6deg)) translate3d(0, -4px, 0);
  box-shadow: 0 30px 60px -30px var(--shadow-card);
  transition-duration: 0.12s;
}

/* O reflexo que segue o ponteiro. Fica sob o texto e não intercepta clique. */
.card::after,
.active::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(
    240px circle at var(--gx, 50%) var(--gy, 0%),
    var(--reflex),
    transparent 62%
  );
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}

.card.is-tilting::after,
.active.is-tilting::after {
  opacity: 1;
}

/* Botões: brilho que atravessa, afundar no clique, seta que desliza -------- */

.button {
  position: relative;
  overflow: hidden;
  /* `outline` não é recortado pelo overflow do próprio elemento, então o anel de
   * foco continua inteiro. */
}

.button--shine::before {
  content: "";
  position: absolute;
  top: -50%;
  bottom: -50%;
  left: -60%;
  width: 40%;
  background: linear-gradient(
    100deg,
    transparent,
    var(--shine),
    transparent
  );
  transform: skewX(-18deg) translate3d(0, 0, 0);
  transition: transform 0.75s cubic-bezier(0.22, 0.61, 0.36, 1);
  pointer-events: none;
}

.button--shine:hover::before,
.button--shine:focus-visible::before {
  transform: skewX(-18deg) translate3d(430%, 0, 0);
}

.button--light.button--shine::before {
  background: linear-gradient(
    100deg,
    transparent,
    var(--shine-soft),
    transparent
  );
}

.button:active {
  transform: translateY(1px) scale(0.985);
}

.button__arrow {
  transition: transform 0.25s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.button:hover .button__arrow,
.button:focus-visible .button__arrow {
  transform: translateX(5px);
}

/* ===========================================================================
 * ALTO CONTRASTE — o que não cabe em um token
 *
 * A espessura das bordas e do foco já vêm de --border-width e --focus-width, e as
 * transparências já foram para cor cheia nos tokens. Sobra o que é estrutura:
 * contorno em superfície que não tinha nenhum, sublinhado em link que tinha sido
 * tirado, e decoração que atrapalha a leitura saindo de cena.
 * ======================================================================== */

/* Toda superfície ganha contorno visível: no preto absoluto, um card sem borda
 * simplesmente não existe. */
:root[data-theme="contrast"] .active,
:root[data-theme="contrast"] .voices figure,
:root[data-theme="contrast"] .offer,
:root[data-theme="contrast"] .summary,
:root[data-theme="contrast"] .panel--outcome,
:root[data-theme="contrast"] .notice,
:root[data-theme="contrast"] .step__error,
:root[data-theme="contrast"] .finale,
:root[data-theme="contrast"] #card-brick,
:root[data-theme="contrast"] .shot__stage,
:root[data-theme="contrast"] .offer__stage,
:root[data-theme="contrast"] .split__figure img,
:root[data-theme="contrast"] .howto__media img,
:root[data-theme="contrast"] .steps__shot {
  border: var(--border-width) solid var(--line);
}

/* Botão sem contorno some no preto; o principal mantém o rosa de fundo, que é
 * requisito, e ganha uma borda branca para separar do fundo. */
:root[data-theme="contrast"] .button {
  border-color: var(--ink);
}

:root[data-theme="contrast"] .button--plain {
  text-decoration-thickness: 2px;
}

/* Link volta a ser sublinhado em todo lugar, inclusive onde o desenho havia
 * tirado o sublinhado. Botão não: ele já se anuncia pela borda e pelo fundo. */
:root[data-theme="contrast"] a:not(.button) {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Decoração que disputa leitura sai: a palavra gigante ao fundo e o reflexo dos
 * cards. As formas desfocadas já saíram pelos tokens --blob-*, e landing-fx.js
 * desliga o parallax e o tilt ao ver este tema. */
:root[data-theme="contrast"] .ghost,
:root[data-theme="contrast"] .card::after,
:root[data-theme="contrast"] .active::after,
:root[data-theme="contrast"] .button--shine::before {
  display: none;
}

/* Nada de desfoque atrás de texto. */
:root[data-theme="contrast"] .chip,
:root[data-theme="contrast"] .topbar.is-stuck {
  backdrop-filter: none;
}

/* O número apagado do passo passa a ser branco cheio: no alto contraste não
 * existe "meio aceso". */
:root[data-theme="contrast"] .fx-on .steps__num {
  color: var(--ink);
}

/* Sem tilt. Aqui em CSS, e não só no JS, para valer na hora em que alguém troca
 * para este tema com o ponteiro parado sobre um card. */
:root[data-theme="contrast"] .card.is-tilting,
:root[data-theme="contrast"] .active.is-tilting {
  transform: none;
  box-shadow: none;
}

/* ---------------------------------------------------------------------------
 * Movimento reduzido
 *
 * Desliga o que se move sozinho — parallax, tilt, faixa infinita, flutuação das
 * etiquetas — e troca as revelações por aparecer sem deslizar. O que sobra é
 * transição de cor e de foco, que ninguém pediu para tirar.
 *
 * Nada de funcional depende de nada disso: a página inteira continua legível,
 * navegável e comprável.
 * ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }

  /* Revelação vira só aparecer, sem subir. */
  .fx-on [data-reveal] {
    transform: none;
  }

  .fx-on [data-reveal].is-in {
    transition: opacity 0.3s ease;
    transition-delay: 0ms;
  }

  .fx-on .word__in {
    transform: none;
    opacity: 1;
  }

  .fx-on [data-reveal].is-in .word__in {
    transition: none;
    transition-delay: 0ms;
  }

  /* Os passos ficam acesos desde o começo. */
  .fx-on .steps__num,
  .fx-on .steps li.is-on .steps__num {
    transform: none;
    color: var(--accent-light);
    text-shadow: none;
  }

  .steps__rail {
    transform: scaleX(1);
    transition: none;
  }

  /* Faixa parada no começo do texto. */
  .marquee__track {
    animation: none;
  }

  /* Etiquetas paradas. */
  .fx-on .chip {
    animation: none;
  }

  /* Sem tilt, sem reflexo, sem afundar. */
  .card.is-tilting,
  .active.is-tilting {
    transform: none;
    box-shadow: none;
  }

  .card::after,
  .active::after {
    display: none;
  }

  .button:active {
    transform: none;
  }

  .button--shine::before {
    display: none;
  }

  .button__arrow {
    transition: none;
  }

  /* No checkout, a troca de etapa e de painel acontece sem esmaecer. */
  .step:not([hidden]),
  .page-co .panel:not([hidden]) {
    animation: none;
  }

  /* O header ainda encolhe ao rolar, mas troca de tamanho de uma vez em vez de
   * deslizar entre os dois estados. */
  .topbar,
  .brand,
  .brand__logo {
    transition: none;
  }
}
