/* ==========================================================================
   RESPONSIVE.CSS — camada responsiva e de acabamento da landing Loomty
   --------------------------------------------------------------------------
   Carregada SEMPRE depois de styles.css (e de preco.css / legal.css).
   Vence por ordem de cascata, não por especificidade inflada: nenhuma regra
   aqui usa !important.

   Segue a lógica desktop-first (max-width) já adotada pelas 16 media queries
   do styles.css. Misturar min-width com o que existe criaria conflito de
   ordem que só se resolveria com !important — que está proibido.

   Breakpoints usados aqui (espelham os do styles.css e acrescentam os que
   faltavam): 1536 / 1280 / 1024 / 768 / 640 / 480 / 360.

   Tudo que é medida vem de token. Tokens de cor, espaço, raio e tamanho de
   toque rastreiam o Loomty DS (Figma TUp2cc5eXoj67ZkUjpw7zi).
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */

:root {
  /* ---- cores RIASEC que faltavam no :root (todas do DS, nada inventado) --
     O styles.css só tinha as bases + amber-light + blue(=E light).
     As variantes light são para texto/ícone sobre fundo escuro; as dark,
     para texto sobre fundo claro onde a base não alcança 4.5:1.          */
  --r-base:  #cc3300;  --r-light: #ff6633;  --r-dark: #7a1e00;
  --i-base:  #cc7700;  --i-light: #ffaa33;  --i-dark: #7a4800;
  --a-base:  #5a8a00;  --a-light: #8ac820;  --a-dark: #2e4800;
  --s-base:  #007a40;  --s-light: #00bb60;  --s-dark: #004422;
  --e-base:  #0044aa;  --e-light: #3377ee;  --e-dark: #002266;
  --c-base:  #6600aa;  --c-light: #9933dd;  --c-dark: #3d0066;

  /* neutros do DS que faltavam */
  --gray-800: #292929;
  --gray-600: #6b6b6b;   /* = --text-grey já existente; nomeado como no DS */
  --gray-400: #a3a3a3;
  --gray-200: #d4d4d4;
  --gray-100: #eaeaea;

  /* ---- escala tipográfica fluida ------------------------------------------
     Uma definição, um lugar. O TETO de cada degrau é o valor do Figma que o
     desktop aprovado já usava — arredondado, nunca inflado — e o PISO é o
     mínimo de legibilidade em mobile (corpo 16px, rótulo 11,5px). Assim o
     desktop se desloca o mínimo possível e o ganho fica onde faltava.
     Fórmula: clamp(min, base + vw, max) — cresce entre 360px e 1280px.

     O CORPO É A EXCEÇÃO, E MUDOU DE NATUREZA
     ----------------------------------------
     Ele já foi fluido (16px no mobile → 17px no desktop) porque o valor do
     Figma, 14,32px, era pequeno demais para ler em qualquer tela. Agora é um
     valor único, 15px, fixo em toda largura — pedido explícito, e a decisão
     inclui abrir mão do piso de 16px que existia por legibilidade em tela
     pequena. Sendo constante, não tem por que continuar sendo clamp: um
     clamp de valor único só esconderia que não há mais faixa nenhuma.       */
  --fs-label:  clamp(11.5px, 11.2px + 0.09vw, 12.5px);  /* Figma 10,34     */
  --fs-2xs:    clamp(12px,   11.7px + 0.09vw, 13px);    /* Figma 11–11,93   */
  --fs-xs:     clamp(13px,   12.7px + 0.09vw, 14px);    /* Figma 11–12,38   */
  --fs-sm:     clamp(14px,   13.7px + 0.09vw, 15px);    /* Figma 13–14      */
  --fs-base:   15px;                                    /* CORPO — fixo, ver acima */
  /* Único degrau nomeado por PAPEL e não por tamanho, e de propósito: ele não
     é um passo da escala, é a exceção que separa o subtítulo do corpo depois
     que o corpo desceu para 15px. Vive aqui, e não solto nos dois seletores,
     para continuar valendo a regra do arquivo — uma definição, um lugar. */
  --fs-lede:   17px;                                    /* SUBTÍTULO de hero e de seção */
  --fs-md:     clamp(16.5px, 16.0px + 0.14vw, 18px);    /* Figma 15,36–15,83*/
  --fs-lg:     clamp(18px,   17.2px + 0.23vw, 20px);
  --fs-xl:     clamp(20px,   18.4px + 0.44vw, 24px);    /* Figma 23,54      */
  --fs-2xl:    clamp(27px,   24.6px + 0.66vw, 33px);    /* Figma 33,09      */
  --fs-display:clamp(30px,   25.0px + 1.40vw, 43px);    /* Figma 42,95      */

  /* alturas de linha (unitless: acompanham o clamp sem apertar) */
  --lh-tight: 1.08;
  --lh-title: 1.18;
  --lh-body:  1.55;
  --lh-label: 1.25;

  /* ---- escala de espaçamento (DS: 8·16·24·32·48·56·72·100·140) ------------
     Os degraus grandes viram fluidos para o mobile não herdar respiro de
     desktop; os pequenos são constantes, como no DS.                        */
  --sp-1: 8px;
  --sp-2: 16px;
  --sp-3: 24px;
  --sp-4: clamp(24px, 21px + 0.83vw, 32px);
  --sp-5: clamp(32px, 25.7px + 1.74vw, 48px);
  --sp-6: clamp(36px, 28.1px + 2.17vw, 56px);
  --sp-7: clamp(44px, 33.1px + 3.04vw, 72px);
  --sp-8: clamp(56px, 38.7px + 4.78vw, 100px);
  --sp-9: clamp(64px, 40.2px + 6.61vw, 140px);

  /* ---- alvo de toque (DS: touch 44 / touch-sm 36) ---- */
  --touch: 44px;
  --touch-sm: 36px;

  /* ---- gutter fluido: substitui o degrau seco 40px -> 20px em 768 ---- */
  /* 20px em 360, exatamente 40px a partir de 1280 — o valor que o desktop
     aprovado já usava, para a conta do palco do hero não se deslocar. */
  --gutter: clamp(20px, 12.17px + 2.174vw, 40px);

  /* ---- áreas seguras (iPhone com notch) ---- */
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
}

/* ==========================================================================
   2. BASE
   ========================================================================== */

/* o corte horizontal do body escondia vazamento real em vez de resolvê-lo;
   mantido, mas agora o conteúdo que vazava foi contido na origem (seção 9). */
html { -webkit-text-size-adjust: 100%; }

/* rolagem com âncora respeitando a nav fixa em qualquer tamanho */
html { scroll-padding-top: clamp(64px, 56px + 2vw, 88px); }

/* o logotipo da nav é o único <img> do site sem width/height declarados:
   reserva o espaço por proporção (160×32) para não gerar CLS na entrada */
.nav-logo-full { aspect-ratio: 5 / 1; }

/* imagem nunca estoura o container, em lugar nenhum */
img, svg, video, canvas { max-width: 100%; }
img:not([width]):not([height]) { height: auto; }

/* código e pré-formatado rolam dentro da própria caixa, nunca no body */
pre, code, kbd, samp { overflow-x: auto; overflow-wrap: anywhere; }

/* tabela rola dentro do wrapper */
.tabela-scroll, .table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}

/* palavras longas (URLs, e-mails) não empurram a coluna em 320px */
p, li, dd, dt, h1, h2, h3, h4, h5, h6, figcaption, blockquote { overflow-wrap: break-word; }

/* ==========================================================================
   3. TIPOGRAFIA — escala nova aplicada às primitivas de LEITURA
   --------------------------------------------------------------------------
   Fora de escopo, deliberadamente: tudo dentro de .mock, .portrait, .pdfm,
   .bank e as classes r* (relatório). Esse conjunto não é texto de leitura —
   é a maquete do app, um frame de 1280px reduzido por transform
   (--mock-escala). Os font-size fracionários de lá são coordenadas do Figma,
   não pixels de tela: aumentá-los quebraria a maquete sem ganho de leitura.
   ========================================================================== */

.eyebrow,
.hero__eyebrow,
.deliver__label,
.persona__meta,
.step__kicker,
.iara__eyebrow,
.layer__meta,
.pr-regra__num,
.stat__label,
.pr-plano__tier {
  font-size: var(--fs-label);
  line-height: var(--lh-label);
}

/* O SUBTÍTULO NÃO É CORPO DE TEXTO
   Os dois primeiros seletores saíram do grupo abaixo quando o corpo caiu para
   15px. Eles não são parágrafo: são a linha única que fica entre o título e o
   conteúdo — o .hero__lede sob o h1 da página, o .lede sob cada título de
   seção. É uma linha que precisa ler como abertura, não como leitura corrida,
   e nos 15px do corpo ela empatava com o texto dos cards logo abaixo.

   17px é o valor que ela tinha antes de tudo isto, e é o que ela volta a ter.
   Fixo, como o resto da escala ficou. */
.hero__lede,
.lede {
  font-size: var(--fs-lede);
  line-height: var(--lh-body);
}

/* daqui para baixo é texto de leitura mesmo: o de dentro dos cards de
   entrega, das camadas, das personas, dos passos e da faixa rolante */
.deliver__text,
.iara__text,
.layer__text,
.persona__text,
.step__body p,
.tick__sub {
  font-size: var(--fs-base);
  line-height: var(--lh-body);
}

.cta__note,
.hero__pausa-dica,
.step__chips span,
.tela__n {
  font-size: var(--fs-2xs);
  line-height: var(--lh-label);
}

/* A nav saiu desta lista. --fs-xs é uma escala fluida (13→14px) e a top bar
   não é fluida: os rótulos dela são 11px/1,54 e o CTA 12px/1,2 — medidas fixas,
   iguais às de loomty.com. Aplicada aqui, a escala engordava o link em ~26% e
   o CTA em ~12%, e era isso que fazia a barra daqui não bater com a de lá.
   Abaixo de 1024px, onde o menu vira lista tocável, ela volta (ver o fim do
   bloco 6). */
.foot-bot,
.foot-col h4 {
  font-size: var(--fs-xs);
}

/* .btn saiu desta lista pelo mesmo motivo que a nav saiu da de cima: o corpo
   do botão é fixo em 12px (--btn-fs), igual ao CTA da topbar. Uma escala
   fluida aqui fazia o mesmo botão medir 13px numa largura e 15px em outra,
   e desalinhava do "JOGAR" que está sempre ao lado, no topo. */
.link-mono,
.foot-col a,
.foot-tag,
.tela__txt {
  font-size: var(--fs-sm);
}

.chip,
.tick__title,
.tela__nome {
  font-size: var(--fs-md);
  line-height: var(--lh-title);
}

.deliver__title,
.layer__name,
.persona__title,
.step__title {
  font-size: var(--fs-xl);
  line-height: var(--lh-title);
}

.layer__num,
.step__num {
  font-size: var(--fs-2xl);
  line-height: var(--lh-tight);
}

.display-54,
.hero__title,
.cta__title {
  font-size: var(--fs-display);
  line-height: var(--lh-tight);
}

/* ==========================================================================
   4. CONTRASTE — WCAG AA (4.5:1 corpo, 3:1 texto grande e ícone)
   --------------------------------------------------------------------------
   Todas as trocas usam variantes oficiais do DS (light sobre escuro, dark
   sobre claro). Nenhuma cor nova foi criada.
   ========================================================================== */

/* --- arquitetura: a tinta vem do contexto, não do seletor -----------------
   O body do site é escuro; as seções claras sobrepõem. Nenhuma cor única
   passa 4,5:1 nos dois fundos ao mesmo tempo (um laranja legível sobre
   #0c0c0c é ilegível sobre #fff e vice-versa), então o contexto precisa
   dizer qual variante usar. Duas custom properties herdadas resolvem isso
   sem multiplicar seletor: a seção declara em que superfície está, e as
   primitivas apenas leem.                                                 */

:root {
  --tinta-eyebrow: var(--r-light);   /* padrão = superfície escura */
  --tinta-mute:    var(--gray-400);
}

/* superfícies claras: mapeadas uma a uma a partir da medição do fundo
   computado de cada .eyebrow/.lede das cinco páginas */
.layers,
.audience,
.admin,
.persona,
.layer,
.report,
.tela,
.channel,
.note,
.legal-content,
.docs-main,
.pr-plano,
.pr-planos,
.pr-regra,
.pr-regras,
.faq,
.faq__item {
  --tinta-eyebrow: var(--r-base);    /* #cc3300 sobre #fff = 4,9:1 */
  --tinta-mute:    var(--gray-600);  /* #6b6b6b sobre #fff = 5,5:1 */
}

.eyebrow,
.hero__eyebrow,
.iara__eyebrow { color: var(--tinta-eyebrow); }

.lede,
.hero__lede,
.tag { color: var(--tinta-mute); }

/* Classe dobrada (0,2,0) — não é truque de especificidade gratuito: o
   styles.css define estes com seletores compostos (.layer .layer__meta e
   afins) e, com 0,1,0, a regra abaixo perderia mesmo vindo depois. Dobrar a
   própria classe é a forma de igualar sem inventar um ancestral que pode
   mudar, e sem !important. */
.persona__meta.persona__meta,
.layer__meta.layer__meta,
.pr-plano__tier.pr-plano__tier,
.pr-plano__nota.pr-plano__nota,
.pr-plano__rollover.pr-plano__rollover,
.per.per,
.pr-feat--no.pr-feat--no,
.pr-feats__grupo.pr-feats__grupo,
.pr-plano__aud.pr-plano__aud,
.pr-qtd__rot.pr-qtd__rot,
.pr-seg__btn span,
.pr-seg__sub.pr-seg__sub,
.channel .tag,
.note .tag,
.docs-hero-note .tag { color: var(--tinta-mute); }

/* Rótulo e numeral coloridos sobre card escuro sobem para a variante light
   do DS.

   A troca é feita por HERANÇA de custom property, não por seletor descendente:
   o card declara qual é a sua variante clara e o rótulo apenas lê. Herança de
   variável não disputa especificidade com as regras compostas do styles.css,
   e continua valendo se o GSAP reescrever o atributo style durante a entrada
   dos cards. O seletor casa só o hex porque esse mesmo GSAP normaliza o
   espaço depois dos dois-pontos — procurar por "--accent:#xxx" falharia
   justamente nos cards animados. */
[style*="#cc3300"]      { --accent-light: var(--r-light); }
[style*="#cc7700"],
[style*="#cc7a06"]      { --accent-light: var(--i-light); }
[style*="#5a8a00"]      { --accent-light: var(--a-light); }
[style*="#007a40"],
[style*="var(--green)"] { --accent-light: var(--s-light); }
[style*="#0044aa"],
[style*="#3377ee"],
[style*="var(--blue-deep)"] { --accent-light: var(--e-light); }
[style*="#6600aa"]      { --accent-light: var(--c-light); }

.deliver__label,
.stat__label,
.pr-passo__num,
/* na página de contato o numeral do card é redefinido por seletor composto
   dentro do <style> da própria página; repetir o seletor é o que iguala */
.delivers__cards .deliver__label { color: var(--accent-light, var(--accent)); }

/* As três regras de contraste do cartão escuro que moravam aqui — escurecer
   o cartão para #0c0c0c, baixar a moldura para #060606 e devolver o hover em
   #111111 com contorno — subiram para o próprio componente, como tokens
   (--card-escuro-*, no :root do styles.css). Eram remendos de especificidade
   presos a `:has(.deliver__label)`, e o guarda nunca chegou a discriminar
   nada: todo .deliver e todo .stat do site têm rótulo. Virando padrão do
   sistema, .stat e .pr-passo passaram a herdar a mesma escada em vez de
   ficarem a meio caminho dela. */

/* --- sobre fundo claro: onde nem a base do DS alcança 4,5:1 --------------
   Âmbar (#cc7700 = 3,24:1) e oliva (#5a8a00 = 3,97:1) são as duas bases que
   falham sobre quase-branco; a variante dark do DS resolve as duas. Classe
   dobrada porque o styles.css as define com seletor composto. */
.faq__num.faq__num,
.pr-regra__num.pr-regra__num { color: var(--i-dark); }

/* selos de módulo da spec: mesmos seletores do legal.css (0,3,0), vindo
   depois na cascata — só a variante dark alcança 4,5:1 no fundo tonal */
.mod-sec.c-r .mod-id { color: var(--r-dark); }
.mod-sec.c-i .mod-id { color: var(--i-dark); }
.mod-sec.c-a .mod-id { color: var(--a-dark); }
.mod-sec.c-s .mod-id { color: var(--s-dark); }
.mod-sec.c-e .mod-id { color: var(--e-dark); }
.mod-sec.c-c .mod-id { color: var(--c-dark); }

/* ==========================================================================
   5. ALVOS DE TOQUE (>= 44x44, espaçamento >= 8px)
   --------------------------------------------------------------------------
   Escopo, e o porquê da exceção: WCAG 2.5.8 isenta explicitamente o link
   embutido em bloco de texto corrido — dar 44px de altura a um link no meio
   de um parágrafo quebraria o parágrafo. Aqui valem os controles: botões,
   itens de menu, itens de índice, ícones e chips.
   ========================================================================== */

/* só min-width/min-height: declarar `display` aqui reacenderia o hambúrguer
   no desktop, onde o styles.css o esconde com display:none. place-content só
   tem efeito se o elemento já for flex/grid, então é seguro.

   .ass__* FICA DE FORA de propósito. O assistente da Iara (iara.html) é uma
   maquete miniaturizada — cada medida sua é o valor do Figma × 0,72, comentado
   assim no próprio CSS do componente ("44 × .72", "36 × .72"...). Um alvo de
   44px ali não é um alvo maior: é OUTRO componente, 1,375× maior que o
   desenhado, e ele estoura a proporção com o resto do cartão (que continua
   pequeno) exatamente como o quadro que motivou este comentário mostrou. A
   mesma lógica que já poupa o .mock do hero (ele nunca entra nesta lista)
   vale aqui: é uma interface simulada em escala reduzida, não um controle de
   página em tamanho real. */
.nav-toggle,
.nav-ai,
.hero__pausa-btn,
.pdfm__close,
.foot-social a {
  min-width: var(--touch);
  min-height: var(--touch);
  place-content: center;
}

/* menu aberto: cada item vira uma faixa de 44px, com 8px entre elas */
.nav.open .nav-links a,
.nav.open .nav-links button,
.nav.is-fechando .nav-links a,
.nav.is-fechando .nav-links button {
  min-height: var(--touch);
  display: flex;
  align-items: center;
}

/* índice lateral das páginas legais e da spec técnica */
.docs-side nav a,
.legal-toc a,
.toc a {
  min-height: var(--touch);
  display: flex;
  align-items: center;
}

/* botões finais e links-âncora do rodapé */
.final-btn { min-height: var(--touch); }

@media (max-width: 768px) {
  /* display:flex (block-level), não inline-flex: o link precisa continuar
     ocupando a largura da coluna do rodapé. Com inline-flex, "Iara" e "LGPD"
     encolhiam para a largura da palavra — 33px de alvo. */
  .foot-col a,
  .foot-bot a {
    min-height: var(--touch);
    display: flex;
    align-items: center;
  }
  .foot-logo,
  .link-mono {
    min-height: var(--touch);
    display: inline-flex;
    align-items: center;
  }
}

/* ==========================================================================
   6. NAVEGAÇÃO MOBILE
   ========================================================================== */

/* No desktop a top bar é a de loomty.com, medida a medida: 73px de altura,
   recuo de 24px à esquerda e 12px à direita, logo de 140×28, links de 11px e
   CTA de 12px. Aqui só se garante que o recuo respeite o entalhe da tela em
   aparelhos com safe area — nunca que ele encolha. */
.nav {
  padding-left: max(24px, var(--safe-l));
  padding-right: max(12px, var(--safe-r));
}

/* De 1024 para baixo o menu já virou lista tocável (styles.css). É onde as
   regras de alvo mínimo entram: elas servem o dedo, e no desktop serviriam
   só para desalinhar a barra da referência.

   O logo é o caso mais claro: <a> de 28px de altura é alvo pequeno demais
   para toque, e por isso ganha 44 aqui embaixo — mas no desktop 28 é a
   medida certa, e era ela que a regra antiga, sem faixa, estava comendo. */
@media (max-width: 1024px) {
  .nav { padding-left: max(var(--sp-2), var(--safe-l)); }
  .nav-logo { min-height: var(--touch); }
  /* .nav-cta saiu daqui: ele é a RÉGUA de todo botão do site (--btn-*), e uma
     escala fluida o fazia crescer para 13–14px abaixo de 1024 enquanto os
     botões de conteúdo ficavam em 12 — a barra passava a destoar justamente
     do que ela define. Os dois vizinhos continuam, porque são links. */
  .nav-link,
  .nav-login { font-size: var(--fs-xs); }
}

/* trava de rolagem sem pulo de layout: a classe é posta pelo nav-a11y.js,
   que compensa a largura da barra de rolagem em --trava-scrollbar. */
html.nav-travado body {
  overflow: hidden;
  padding-right: var(--trava-scrollbar, 0px);
}

@media (max-width: 768px) {
  .nav.open .nav-links,
  .nav.is-fechando .nav-links {
    padding-bottom: max(var(--sp-3), var(--safe-b));
    max-height: calc(100svh - 72px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* foco visível em tudo que recebe foco — inclusive onde o autor removeu */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
  border-radius: 2px;
}

/* ==========================================================================
   7. ALTURA DE VIEWPORT — 100vh mente no Safari iOS
   --------------------------------------------------------------------------
   svh = viewport com a barra de endereço visível: é o valor seguro para
   "caber na tela" sem que o conteúdo suma sob a barra.
   ========================================================================== */

@supports (height: 100svh) {
  .hero {
    /* as três contas do hero têm de trocar juntas: a altura do bloco, a faixa
       do texto e a escala do palco saem todas do mesmo orçamento vertical.
       Trocar só o `height` deslocaria a maquete dentro do quadro. Fórmulas
       idênticas às do styles.css, com svh no lugar de vh. */
    /* mesmo piso do styles.css: 280px é a altura medida do bloco com o CTA */
    --texto-alt: max(280px, calc((100svh - 73px) * var(--faixa-texto)));
    --mock-escala: clamp(.5,
        calc((100svh - 129px - var(--texto-alt)) / 766.989px),
        min(calc((var(--vw-util, 100vw) - 2 * var(--gutter)) * var(--tela-do-palco) / 1280px), 1.35));
    height: 100svh;
  }
  .bento-scrub .gallery-wrap { height: 100svh; }
}

@media (prefers-reduced-motion: reduce) {
  .bento-scrub .gallery-wrap { min-height: 100svh; }
}

/* paisagem em celular: 390px de altura não comporta um hero de tela cheia */
@media (max-height: 480px) and (orientation: landscape) {
  .hero { height: auto; min-height: 0; padding-top: 92px; padding-bottom: var(--sp-5); }
  .bento-scrub .gallery-wrap { height: auto; min-height: 0; }
}

/* ==========================================================================
   8. FORMULÁRIOS — iOS dá zoom em input com fonte < 16px
   ========================================================================== */

input, select, textarea {
  font-size: max(16px, 1em);
}

@media (max-width: 768px) {
  input:not([type=checkbox]):not([type=radio]),
  select,
  textarea,
  button[type=submit] {
    min-height: var(--touch);
  }
}

/* ==========================================================================
   9. VAZAMENTOS HORIZONTAIS CONTIDOS NA ORIGEM
   --------------------------------------------------------------------------
   O body corta o excedente com overflow-x:hidden. Isso escondia o sintoma:
   os elementos abaixo continuavam mais largos que a tela e tinham parte do
   conteúdo inacessível. Aqui eles passam a caber.
   ========================================================================== */

/* A barra da nav é o ponto mais apertado do site: logotipo (140px fixos) +
   "Jogar" + hambúrguer + atalho da Iara. Com os controles subindo para os
   44px de alvo mínimo, o conjunto passava de 320px e o body cortava a ponta
   do atalho da Iara.

   loomty.com resolve isso trocando o lockup inteiro (símbolo + "loomty") só
   pelo símbolo abaixo de 768px — não encolhendo a marca completa, que numa
   faixa estreita vira ilegível de qualquer forma. Mesma troca aqui: o
   símbolo é outro arquivo (icon-loomty[-white].svg, direto do site no ar),
   não um recorte por CSS da marca completa. */
@media (max-width: 768px) {
  .nav-logo-full { display: none; }
  /* `.nav.scrolled .nav-logo-full-dark { display: block }` (styles.css) tem
     duas classes — 0,2,0 — e vence a regra de cima (0,1,0) mesmo vindo
     depois na cascata. Repetir os dois seletores, um a um, iguala a
     especificidade nos dois estados (rolado e não-rolado) sem precisar de
     !important. */
  .nav.scrolled .nav-logo-full-light,
  .nav.scrolled .nav-logo-full-dark { display: none; }
  .nav-logo-icon {
    display: block;
    width: 32px;
    height: 32px;
  }
  .nav-logo-icon-dark { display: none; }
  .nav.scrolled .nav-logo-icon-light { display: none; }
  .nav.scrolled .nav-logo-icon-dark { display: block; }

  /* a caixa vira quadrada e centraliza o símbolo — a largura fixa de 140px
     era pensada pro lockup horizontal, que não existe mais aqui */
  .nav-logo {
    flex: 0 0 var(--touch);
    width: var(--touch);
    height: var(--touch);
    justify-content: center;
  }
}

@media (max-width: 380px) {
  .nav { padding-left: max(12px, var(--safe-l)); padding-right: max(8px, var(--safe-r)); }
  .nav-actions { gap: 4px; }
  /* o aperto do CTA (9px de respiro, entreletra zerada) saiu daqui: era
     herança de quando a marca completa aparecia nesta faixa. Hoje abaixo de
     768 quem fica é só o símbolo, e medido em 320px o botão cabe com os 22px
     da régua sem empurrar nada — a barra continua em 320 de largura. */
}

/* o par de botões do CTA final: em 320px o rótulo mais longo não cabe na
   caixa e empurrava o documento 19px para a direita */
@media (max-width: 480px) {
  .cta__buttons { width: 100%; flex-direction: column; }
  .cta__buttons .btn,
  .cta__actions .btn {
    width: 100%;
    max-width: 100%;
    white-space: normal;
    text-align: center;
  }
}

/* tabela larga: rola dentro da própria caixa, com foco por teclado.
   O wrapper .tbl-scroll foi acrescentado no HTML (spec-tecnica) porque não
   existe forma de embrulhar um elemento só com CSS sem transformar a
   <table> em bloco — o que a tira da árvore de acessibilidade como tabela. */
.tbl-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  max-width: 100%;
}
.tbl-scroll:focus-visible { outline: 2px solid var(--r-light); outline-offset: 2px; }

/* NÃO mexer na galeria bento: as colunas em 46vw somam mais que a tela de
   propósito — é um mosaico maior que a janela, escalado e recortado pelo
   scrub do ScrollTrigger. Prendê-lo em 100% desmontaria a animação. Ele
   aparece no laudo como "overflow contido" e é o único caso legítimo. */

/* ==========================================================================
   10. MOVIMENTO — a preferência do sistema manda
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  /* O reveal por scroll já está coberto na origem: o cards-reveal.js checa a
     preferência ANTES de esconder qualquer coisa, e o estado oculto nunca
     chega ao DOM. Nada a fazer aqui — e por isso este arquivo não tem
     nenhum !important.
     O que faltava era a maquete do hero, que anima em laço próprio: */
  .mock, .mock *, .hero__stage, .hero__stage * {
    animation: none;
    transition: none;
  }
}

/* ==========================================================================
   11. HERO EM CELULAR — a maquete volta a ser um quadro ancorado na base
   --------------------------------------------------------------------------
   No desktop a maquete é uma caixa de 1280×767 posicionada em absoluto,
   presa em `bottom: 0` e reduzida por `scale()`: é isso que a mantém colada
   na base do palco e do tamanho do espaço que sobra. Abaixo de 1360px o
   styles.css desmonta esse arranjo (position: static, transform: none) e a
   maquete passa a ser fluida no fluxo — o que em celular produzia o quadro
   preto vazio com só o cabeçalho do app dentro.

   Aqui a MECÂNICA do desktop volta, com a maquete em formato de celular: o
   palco toma o que resta do orçamento vertical do hero e a maquete preenche
   esse palco de baixo para cima. A diferença é que agora ela cabe pela
   ALTURA em vez de pela escala — em 335px de largura, reduzir 1280px por
   transform daria uma UI de 26% do tamanho original, ilegível.
   ========================================================================== */

/* A faixa é ≤1360, e não ≤768, porque é aí que o styles.css desmonta o
   arranjo do desktop: dali para baixo o hero e a maquete estão no mesmo
   estado, e o conserto é o mesmo. Duas das três telas da maquete declaram
   `flex: 1 0 0`, e base ZERO só vira altura quando o contêiner tem altura
   própria para repartir — num .mock de altura automática ela resolve para
   zero, que é por que o retrato e o relatório sumiam por inteiro de 1360px
   para baixo. Devolvendo altura ao .mock, a base zero volta a funcionar
   exatamente como no desktop. */
@media (max-width: 1360px) {
  /* VOLTA para janela de altura FIXA, com rolagem própria por dentro —
     revertendo a tentativa anterior ("herói de altura de conteúdo", como o
     .ih de iara.html). Testado ao vivo, o relatório sozinho é tantas vezes
     mais alto que o quiz que o herói inteiro inchava e encolhia à vista do
     visitante a cada troca de tela da demonstração automática, empurrando o
     resto da página sem aviso. O pedido concreto — "o limite visível do
     palco deve ter a altura do quadro vermelho" — pede de volta um quadro
     de tamanho ESTÁVEL, com a leitura revelada por rolagem interna.

     700px, e não mais a conta "100svh − texto − nav": é o MESMO valor fixo
     que --ass-h usa no assistente de iara.html (`min(700px, 100vh − 216px)`)
     — a mesma referência de tamanho "confortável" que já vale nesta página,
     em vez de uma fórmula que persegue a altura da janela. */
  .hero { height: auto; overflow: visible; }
  .hero__inner { height: auto; min-height: 0; }
  .hero__copy { flex: 0 0 auto; }

  .hero__stage {
    flex: none;
    height: min(700px, calc(100svh - 216px));
    display: flex;
  }
  /* O quadro é FIXO — o mesmo tamanho em qualquer passo da demonstração,
     sem exceção nem para a gaveta do banco de palavras (§15): é o mesmo
     princípio do .ass-pilha em iara.html (--ass-h: min(700px, 100vh−216px),
     um valor só, nunca sobrescrito). O que não coube no conteúdo da gaveta
     rola por dentro dela (.portrait__bank já tem overflow-y:auto) — o palco
     nunca incha para caber conteúdo. */
  /* SEM moldura própria: nesta faixa o "frame pai" (o fundo decorativo do
     palco, que no desktop emoldura a tela com um respiro de 24px medidos na
     escala) deixa de existir como objeto visível. */
  .hero__stage::before { display: none; }

  /* o seletor com atributo é o que o styles.css usa para soltar a altura na
     tela do retrato (`.mock[data-view="portrait"] { height: auto }`), e ele
     ganha de `.mock` por especificidade — vir depois na cascata não bastaria.
     Repetir a dupla é o que iguala sem inventar um ancestral nem !important.

     border-radius nos quatro cantos, não só em cima: com o respiro que
     agora existe depois do herói (a seção anterior), a base quadrada da
     maquete deixou de "encostar no chão" — sobra fundo escuro visível
     embaixo dela, e ali um canto reto lia como um recorte inacabado. */
  .mock,
  .mock[data-view="portrait"] {
    height: 100%;
    min-height: 0;
    /* a base encosta no chão do palco, como no desktop */
    align-self: flex-end;
    border-radius: var(--radius-16);
  }

  /* a maquete tem altura outra vez, então o miolo dela volta a ser elástico:
     as telas dividem o que sobra abaixo da barra superior */
  .mock__body { flex: 1 1 auto; min-height: 0; }
  .mock__stage {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    align-items: center;
  }
  /* as duas telas altas rolam dentro da própria janela — é essa rolagem que
     a demonstração automática percorre, exatamente como no desktop */
  .portrait,
  .report {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* O botão de pausa flutua sobre o canto de baixo da maquete, como o
     controle de um player de vídeo. Fica por DENTRO do quadro (não mais
     escapando por cima dele): a tela cola na base do palco, sem respiro
     reservado embaixo, então não há para onde o botão fugir por FORA —
     o `z-index` garante que ele vença o conteúdo por baixo dele. */
  .hero__pausa {
    top: auto;
    bottom: 16px;
    right: 16px;
    /* nesta faixa .mock roda com `position:static` e sem transform — não é
       uma stacking context própria, então qualquer z-index declarado lá
       dentro (a gaveta usa 6, o mesmo do botão) escapa e compete DIRETO com
       o do botão no mesmo nível. Empatados, quem vem depois no HTML vence —
       e é o .mock, que sucede o .hero__pausa. Um z-index bem acima resolve
       sem ambiguidade, em qualquer tela por baixo. */
    z-index: 20;
  }
  .hero__pausa-dica { top: auto; bottom: calc(100% + 8px); }
}

@media (max-width: 768px) {
  /* respiro no final da seção: sem ele, a base do quadro (onde mora o botão
     de pausa) encostava direto na próxima seção, sem nenhum ar entre os
     dois — a página parecia continuar sem pausa nenhuma */
  .hero { padding: 92px var(--gutter) var(--sp-6); }
  .hero__stage { margin-top: 48px; }
  .mock__stage { padding: 18px 14px; }
  .report__col { padding: 24px 18px 32px; }

  /* a maquete em 335px: os alvos do quiz ocupam a linha inteira, dois a dois,
     e a pergunta ganha a largura toda do cartão */
  .mock__card { width: 100%; }
  .mock__tbtn span { display: none; }
  .mock__tbtn { width: auto; }
  .mock__saved { display: none; }
  /* o rodapé do app ("nos avise sobre perguntas estranhas") quebra em duas
     linhas nesta largura e cai debaixo do botão de pausa, que mora na mesma
     quina. É um aviso de dentro do produto, não da página: some daqui e
     continua onde tem função, que é no jogo. */
  .mock__foot { display: none; }

  /* as abas do relatório não cabem em 320px de janela e a última ficava
     cortada no meio da palavra. Como no app de verdade, a fileira desliza. */
  .rnav__tabs {
    overflow-x: auto;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
  }
  .rnav__tabs::-webkit-scrollbar { width: 0; height: 0; }
  .rnav__tabs > * { flex: none; scroll-snap-align: start; }
}

/* ==========================================================================
   12. GRUPOS DE CARTÕES — carrossel com paginação em celular
   --------------------------------------------------------------------------
   Empilhados, os três grupos de cartões (as quatro camadas, as três
   entregas, os três públicos) viravam 1.300px de rolagem vertical cada um.
   Em celular eles passam a ser uma faixa que desliza na horizontal, com
   encaixe por cartão e a paginação logo abaixo — setas, contador e pontos.

   A faixa é o PRÓPRIO contêiner que já existia (.layers__grid,
   .delivers__cards, .audience__cards): ele já é a moldura arredondada do
   grupo, então virar trilho é só trocar o embrulho, sem nível novo de DOM.
   A barra de paginação é criada pelo carrossel.js e só existe onde ela tem
   função — sem JavaScript, o grupo continua sendo uma faixa que desliza.
   ========================================================================== */

@media (max-width: 768px) {
  .carrossel {
    /* os grupos chegam aqui em arranjos diferentes — um empilha em coluna,
       outro embrulha e centra. Como trilho, todos precisam ser a mesma
       coisa: uma fileira que começa na borda. `center` em especial é
       incompatível com rolagem: ele empurra o excedente para os DOIS lados e
       o primeiro cartão fica em posição negativa, inalcançável.

       `display:flex` entrou quando as três faixas de /preco chegaram: duas
       delas (.pr-fluxo__grade e .pr-regras__grade) são GRID, e num grid de
       uma coluna as declarações de flex abaixo não têm efeito nenhum — os
       cartões continuariam empilhados dentro de um contêiner que rola na
       horizontal e nunca precisa rolar. Nas faixas que já eram flex a
       declaração não muda nada. */
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: flex-start;
    align-items: stretch;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    /* a barra de rolagem some porque a paginação abaixo já diz onde se está;
       duas indicações da mesma coisa competem entre si */
    scrollbar-width: none;
    /* o encaixe alinha o cartão à borda interna da moldura, não à externa:
       sem isso o respiro da moldura desaparece a partir do segundo cartão */
    scroll-padding-inline-start: var(--carrossel-respiro, 8px);
  }
  .carrossel::-webkit-scrollbar { width: 0; height: 0; }

  /* A seção "para quem" centra o próprio miolo (`align-items: center`), e um
     item de flex centrado se dimensiona pelo CONTEÚDO. Virando trilho, o
     conteúdo passou a ser a soma dos três cartões: o miolo esticava para
     1.156px e arrastava a seção com ele. Travar a largura do miolo desfaz a
     circularidade — o trilho mede a partir da seção, não o contrário. */
  .audience__inner { width: 100%; max-width: 100%; }
  /* width:100%, e não só min/max: .delivers__cards em iara.html tem
     `width:var(--content)` própria (1280px — a página tem 4 entregas em vez
     de 3, e o comentário ali explica por que a largura precisa ser
     declarada). Sem um `width` que vença o dela, o max-width:100% sozinho
     resolve contra o conteiner (que também não está preso à tela), e a
     faixa nasce larga demais para caber — o próprio scroll-snap então
     ancora fora do que se vê. */
  .carrossel { width: 100%; min-width: 0; max-width: 100%; }

  /* EXCEÇÃO: TRILHO COM MARGEM LATERAL PRÓPRIA.
     `width:100%` mede o PAI e ignora a margem do próprio elemento. Num
     trilho sem margem os dois valores coincidem, e foi assim que a regra
     acima nasceu. Mas a faixa de planos da /preco tem `margin: 0 24px`
     (preco.css) para alinhar com a grade: com 100% ela nascia do tamanho da
     seção inteira e, começando 24px adentro, terminava 24px DEPOIS da borda
     da tela. O resultado era a página inteira rolando na horizontal — a
     barra fixa ficava parada e o conteúdo deslizava por baixo dela.

     A própria preco.css já pedia `width:auto`, que é o valor certo para
     quem tem margem (auto = o que sobra do pai depois das margens). Só que
     esta folha carrega DEPOIS e, com a mesma especificidade, anulava aquilo
     em silêncio. Dobrar a classe vence o empate sem depender da ordem. */
  .pr-grade.carrossel { width: auto; }

  /* .delivers__block é o elo que faltava. .delivers (a seção) centraliza os
     filhos em vez de esticá-los (`align-items:center`), então quem não tiver
     largura própria vira do tamanho do CONTEÚDO — e min-width:auto (o
     padrão de todo item de flex) proíbe esse conteúdo de encolher abaixo do
     próprio mínimo. .delivers__stack e .delivers__head já têm width:100%,
     mas 100% de um pai sem tamanho definido não resolve nada; sobe pela árvore até
     achar um que tenha. Na home a árvore some antes de chegar tão alto
     (.layers__inner já resolve um nível acima); aqui, com o nível extra do
     .delivers__block, ninguém resolvia — e é a faixa de cartões (a única
     coisa ali que não quer ficar do tamanho do próprio conteúdo) quem paga
     o preço, saindo mais larga que a tela. */
  .delivers__block { width: 100%; min-width: 0; }

  /* `.carrossel.carrossel` — classe dobrada, não capricho: iara.html tem a
     própria regra para dividir a largura dos cards pela quantidade que
     existe na página (".layers__grid .layer { flex:1 1 0 }", specificidade
     0,2,0, porque lá o número de cards muda por seção). Um seletor de
     especificidade 0,1,0 como `.carrossel > *` perde essa disputa mesmo
     vindo depois no CSS — na home não há regra concorrente, então o efeito
     nunca apareceu lá. Dobrar a classe iguala a 0,2,0 sem inventar um
     ancestral que pode não existir amanhã; o empate se resolve por quem
     carrega depois (responsive.css, sempre por último). */
  .carrossel.carrossel > * {
    /* o cartão seguinte fica à vista pela beirada: é o que avisa que a faixa
       anda, antes mesmo de a paginação ser lida */
    flex: 0 0 calc(100% - 52px);
    width: calc(100% - 52px);
    max-width: none;
    scroll-snap-align: start;
  }

  /* ---- .iara__stack como trilho ----
     Os três passos foram desenhados para se ENCOSTAR (sem vão entre eles,
     ver BLOCOS_UNIDOS em cards-reveal.js) e para abrir só com hover — nenhum
     dos dois faz sentido num trilho de toque: aqui vira um cartão a mais
     entre os outros, com o mesmo encaixe e a mesma paginação.

     `height: auto` (herdado do ≤1024) já tira a pilha do modo acordeão; falta
     só o card não depender de :hover para se ler "aberto", já que em toque
     não existe :hover persistente — sem isso os três ficariam com o véu
     escuro de repouso, o número apagado e o corpo (que ≤1024 já força
     visível) lendo sobre um fundo mais escuro do que o das outras seções. */
  .iara__stack.carrossel { gap: 0; }
  .step {
    /* mesma largura de qualquer outro cartão do trilho — o `flex:1 1 auto`
       do ≤1024 (pensado pra dividir a ALTURA da pilha) perde a função aqui,
       já que `.carrossel > *` acima já resolve a largura */
    min-height: 260px;
  }
  .step::before { opacity: .18; }
  .step__num { color: rgba(255, 255, 255, .58); }

  /* ---- a barra de paginação ---- */
  .carrossel-nav {
    --nav-tinta: var(--ink);
    --nav-borda: rgba(12, 12, 12, .16);
    --nav-fraco: rgba(12, 12, 12, .28);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
  }
  /* nas seções escuras a mesma barra inverte por variável, não por outro
     conjunto de regras */
  .delivers .carrossel-nav,
  .pr-fluxo .carrossel-nav,
  .ip-sec--escuro .carrossel-nav,
  /* o herói da /contato é escuro e não carrega nenhuma das classes de
     superfície acima: sem ele nesta lista a barra nascia #0C0C0C sobre
     #090909 — presente no DOM, invisível na tela. */
  .chero .carrossel-nav,
  .iara .carrossel-nav {
    --nav-tinta: var(--paper-fa);
    --nav-borda: rgba(255, 255, 255, .18);
    --nav-fraco: rgba(255, 255, 255, .34);
  }
  /* a barra nasce logo abaixo da pilha, dentro do mesmo grid de 1 coluna —
     sem este respiro ela colava direto na sombra do último cartão */
  .iara .carrossel-nav { margin-top: var(--sp-3); }
  /* mesmo caso na /contato: o trilho é a moldura de 8px dos quatro
     cartões de atendimento, e a barra nascia encostada nela. */
  .chero__stats + .carrossel-nav { margin-top: var(--sp-3); }

  /* ---- as três faixas de /preco ----
     .pr-planos é um flex que CENTRA o filho único (a grade). Com a barra
     inserida ao lado dela, os dois viravam colunas lado a lado; em coluna,
     a barra volta para baixo do trilho. A margem horizontal é a mesma que
     preco.css dá à grade em celular (24px), para a barra terminar
     exatamente onde o trilho termina. */
  .pr-planos { flex-direction: column; align-items: stretch; }

  /* A faixa dos planos se mede por MARGEM (`margin: 0 24px`, em preco.css),
     não por largura. O `width: 100%` que todo trilho recebe lá em cima —
     regra escrita para a `.delivers__cards` da /iara, que carrega uma
     largura própria de 1280px — soma-se às duas margens e empurra a faixa
     24px PARA FORA da borda direita da tela. O efeito era assimétrico e
     visível: à esquerda o cartão anterior aparecia pela beirada, como manda
     o modelo, e à direita o cartão do fim encostava no bico do aparelho,
     sem respiro nenhum. Aqui a largura volta a ser "o que sobra entre as
     margens". */
  .pr-planos .carrossel { width: auto; }
  .pr-planos .carrossel-nav { margin: 16px 24px 0; }
  .layers__inner .carrossel-nav,
  .delivers__stack .carrossel-nav,
  .ip-in .carrossel-nav { margin-top: var(--sp-3); }

  .carrossel-nav__btn {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--touch);
    height: var(--touch);
    padding: 0;
    border: 1px solid var(--nav-borda);
    border-radius: 10px;
    background: transparent;
    color: var(--nav-tinta);
    cursor: pointer;
    appearance: none;
    transition: border-color .2s ease, background-color .2s ease, opacity .2s ease;
  }
  .carrossel-nav__btn svg { width: 18px; height: 18px; display: block; }
  .carrossel-nav__btn:disabled { opacity: .3; cursor: default; }
  .carrossel-nav__btn:not(:disabled):hover { border-color: var(--nav-tinta); }

  .carrossel-nav__mid {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
  }

  .carrossel-nav__contador {
    margin: 0;
    font-family: var(--mono);
    font-weight: 700;
    font-size: var(--fs-2xs);
    letter-spacing: .14em;
    color: var(--nav-tinta);
    font-variant-numeric: tabular-nums;
  }

  .carrossel-nav__pontos { display: flex; align-items: center; gap: 6px; }
  .carrossel-nav__ponto {
    position: relative;
    width: 6px;
    height: 6px;
    padding: 0;
    border: 0;
    border-radius: 99px;
    background: var(--nav-fraco);
    cursor: pointer;
    appearance: none;
    transition: width .28s var(--ease-out, ease), background-color .28s ease;
  }
  /* o ponto ativo vira traço: a posição na faixa se lê pela forma, e não só
     pelo tom — que é o que sobrevive a daltonismo e a tela sob sol */
  .carrossel-nav__ponto[aria-current="true"] {
    width: 20px;
    background: var(--nav-tinta);
  }

  /* o alvo de toque tem os 44px exigidos sem que o desenho do ponto cresça:
     quem é ampliado é a área clicável, não a forma */
  .carrossel-nav__ponto::before {
    content: "";
    position: absolute;
    inset: calc((var(--touch) - 6px) / -2) -4px;
  }
}

/* acima de 768 a faixa é desmontada pelo script; estas regras nem chegam a
   valer, mas a barra fica escondida de qualquer forma — é a garantia de que
   um resize no meio do caminho não deixa a paginação órfã no desktop */
@media (min-width: 769px) {
  .carrossel-nav { display: none; }
}

/* ==========================================================================
   13. GALERIA BENTO — o scrub estava desligado em celular
   --------------------------------------------------------------------------
   O efeito depende de `position: sticky` na .gallery-wrap. Abaixo de 768px o
   styles.css põe `overflow: hidden` na SEÇÃO, e um ancestral com overflow
   diferente de `visible` vira o contêiner de rolagem daquele sticky — um
   contêiner que nunca rola, então o sticky nunca gruda: a galeria subia e
   saía da tela junto com a página, sem nenhum scrub.

   `clip` corta igual a `hidden` e não cria contêiner de rolagem, que é
   exatamente a diferença que importa aqui. O `hidden` continua na
   .gallery-wrap, onde ele é o recorte legítimo do mosaico.
   ========================================================================== */

@media (max-width: 768px) {
  .bento-scrub { overflow: clip; }

  /* o estado de repouso da grade (o que vale antes do primeiro scroll e sem
     JavaScript) tem que ser o mesmo ponto de partida que o scrub usa — ver
     extremos() no index.html */
  .bento-scrub .gallery--bento {
    grid-template-columns: repeat(3, var(--col, 31vw));
    grid-template-rows: repeat(4, var(--row, 21.5vh));
  }
}

/* ==========================================================================
   14. AS DUAS TELAS DO PAINEL — apresentação em celular
   --------------------------------------------------------------------------
   No desktop cada tela é uma JANELA mais baixa que a imagem que carrega: o
   cabeçalho fica parado por cima (.tela__cromo) e o miolo rola por baixo,
   revelando o resto da captura sem que a PÁGINA acompanhe — só o conteúdo de
   dentro da janela se move. A janela é dimensionada em % do palco
   (`height: 66%`), e abaixo de 768px o palco vira `display: contents` —
   some, e com ele a altura de referência. As duas telas ficavam com 2px de
   altura: invisíveis.

   Aqui a mesma mecânica volta, do tamanho de uma tela de celular: cada
   `.tela` ganha uma altura própria (`--tela-alt`, em vh — a mesma unidade
   que a maquete do hero usa para caber na tela real do aparelho), o cromo
   continua fixo por cima e o `.tela__rolo` rola por baixo dele, sozinho —
   exatamente como no desktop, só que a rolagem acontece por arraste do dedo
   em vez de hover do mouse.

   `overflow-y: auto` fica incondicional aqui (não depende de `data-foco`
   como no desktop): não existe hover em toque, e as duas telas já ficam
   sempre acesas nesta faixa — sem o "foco" que no desktop decide qual delas
   pode rolar, a decisão simplesmente deixa de existir, e as duas passam a
   poder rolar sempre.

   Cada tela nasce logo abaixo da explicação que a apresenta (a ordem já vem
   do styles.css), então o par número → texto → imagem se lê como um bloco.
   ========================================================================== */

@media (max-width: 768px) {
  .telas { gap: var(--sp-4); }
  .telas__legendas { gap: var(--sp-4); }

  /* o filete que desce do numeral amarra o par; em pilha ele não tem mais
     um bloco alto para percorrer e vira um traço solto */
  .tela__n { padding-bottom: 20px; }
  .tela__txt { max-width: none; }

  /* A janela muda de FORMA (mais alta, menos larga que no desktop — cabe
     melhor numa tela de celular), mas o recorte do cromo (--lado, --cab,
     --cab-w) foi calculado para a proporção larga do desktop, e não muda
     sozinho junto com o `aspect-ratio`.

     --cab-w não depende da forma da janela: é a altura do cabeçalho, em %
     da LARGURA renderizada, e a largura continua sendo 100% da janela em
     qualquer proporção — por isso o valor do desktop (5,750% / 10,731%)
     continua certo aqui, sem tocar nele.

     --cab é diferente: é a MESMA altura de cabeçalho, mas em % da ALTURA da
     janela — e a altura muda com a forma. A conta é cab% = cab-w% × (largura
     ÷ altura da janela); aqui embutida já resolvida para a proporção nova.
     Pular essa conta e herdar o --cab do desktop foi o que duplicava o
     cabeçalho: a rolagem parava mais abaixo do que o cromo cobria, sobrando
     uma segunda cópia do topo entre os dois.

     A proporção em si (3∶2 — a mesma do palco desktop, só que aplicada à
     largura cheia do celular) veio de um primeiro corte alto demais (3∶4):
     dava para ler quase o painel inteiro dentro da janela — funil, perfis,
     cursos, saúde, fila de ação e partidas recentes, tudo de uma vez — e aí
     a janela parava de se comportar como um recorte e virava só "a imagem,
     um pouco menor". 3∶2 mostra o cabeçalho e as duas primeiras fileiras
     (indicadores + funil/perfis) e deixa claro que rolar revela mais. */
  .tela {
    position: relative;
    inset: auto;
    width: 100%;
    /* `.tela--painel`/`.tela--relatorio` (styles.css, sem media query)
       fixam height:66%/72% — sem cancelar aqui, essa altura vence e o
       aspect-ratio abaixo nunca chega a calcular nada: `height` explícito
       sempre tem prioridade sobre a altura que o aspect-ratio preencheria. */
    height: auto;
    aspect-ratio: 3 / 2;
    /* encosta na explicação que a apresenta, dentro do gap da pilha */
    margin-top: calc(var(--sp-4) * -0.5);
  }
  /* --cab = --cab-w × 1,5, porque aqui a janela é 3∶2 para as duas telas.
     Atualizado em 19/08/2026 junto com as capturas novas: --cab-w passou a
     5,750% (painel) e 10,731% (relatório). */
  .tela--painel    { --cab: 8.625%; }
  .tela--relatorio { --cab: 16.0965%; }

  /* a rolagem é SEMPRE do visitante aqui — sem hover, não existe um estado
     "em foco" que a libere só numa tela por vez, como no desktop */
  .tela__rolo {
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: rgba(12, 12, 10, .22) transparent;
  }

  /* nada aqui reage a hover em toque: as duas telas ficam sempre acesas, e
     o zoom de 1.12 que o desktop aplica na tela "em foco" — pensado para o
     ponteiro do mouse pousar em cima — não tem por que disparar aqui: um
     toque na tela é a intenção de rolar, não de ampliar. */
  .telas[data-foco] .tela,
  .telas[data-foco="painel"] .tela--relatorio,
  .telas[data-foco="conta"] .tela--painel { opacity: 1; }
  .telas[data-foco="painel"] .tela--painel,
  .telas[data-foco="conta"]  .tela--relatorio { transform: none; }
}

/* ==========================================================================
   15. A TELA DO RETRATO EM CELULAR — frames 254:2029 e 255:2039
   --------------------------------------------------------------------------
   No desktop as três frases e o banco de 36 palavras convivem na mesma tela:
   sobra largura para a linha ser uma faixa horizontal (rótulo · fichas ·
   contador) e altura para o banco morar embaixo delas.

   Em 335px nenhuma das duas coisas se sustenta. A faixa horizontal deixaria
   ~120px para as fichas, e o banco sozinho tem 36 palavras — empilhado com as
   linhas, empurraria o retrato inteiro para fora da janela.

   Os frames resolvem separando o que compete por espaço em dois tempos:

   · a LINHA vira um cartão — rótulo e contador no alto, fichas embaixo, e a
     cor da frase num filete à esquerda, que é o que ainda distingue as três
     de relance quando não há largura para mais nada;

   · o BANCO vira uma GAVETA que sobe sobre as linhas quando é hora de
     escolher, e sai de cena quando não é. Ela diz para qual frase a palavra
     vai, na cor daquela frase, porque aberta ela cobre justamente a linha que
     responderia essa pergunta.

   O estado da gaveta é uma classe no .portrait (posta em index.html). A folha,
   o escurecimento do fundo e a barra de ações leem todos do mesmo lugar.
   ========================================================================== */

/* O cabeçalho da gaveta existe no HTML em todas as larguras e só entra em
   cena abaixo de 768 — declarado fora da media query porque o padrão, aqui, é
   ele NÃO aparecer: no desktop não há gaveta, o banco é uma lista na página e
   um cabeçalho de folha ali seria uma moldura sem folha. */
.pbank__head { display: none; }

@media (max-width: 768px) {

  /* ---- o quadro: quem rola é a coluna, não a tela ----
     A gaveta e a barra de ações são absolutas e precisam ficar PARADAS
     enquanto o conteúdo passa por trás. Um elemento absoluto só escapa da
     rolagem se o bloco que o contém estiver fora do que rola — por isso a
     .portrait vira o bloco de contenção (relative) e a rolagem desce um
     nível, para a .portrait__col. */
  .portrait {
    position: relative;
    display: block;
    /* NÃO hidden: o escurecimento de fundo da gaveta (ver .portrait__vocab
       mais abaixo) é a sombra da própria folha, espalhada até cobrir a tela
       inteira — cabeçalho do app incluído. Um `overflow:hidden` aqui
       cortaria essa sombra na borda da .portrait, que começa DEPOIS do
       cabeçalho, e o app ficaria com uma faixa clara no topo por cima do
       resto escurecido. Quem ainda clipa é o `overflow:hidden` do .mock
       (a moldura arredondada da tela), dois níveis acima — a sombra pode
       crescer à vontade que não escapa da tela. A rolagem interna não
       depende deste overflow: .portrait__col já clipa o próprio conteúdo
       com o `overflow-y:auto` dela. */
    overflow: visible;
    padding: 0;
  }
  .portrait__col {
    width: 100%;
    height: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    /* o vão de baixo é a altura da barra de ações, que flutua sobre a coluna */
    padding: 18px 16px 78px;
    gap: 18px;
  }

  .portrait__eyebrow { font-size: var(--fs-label); letter-spacing: .11em; }
  .portrait__title { font-size: 21px; letter-spacing: -.3px; }

  /* ---- a linha vira cartão ---- */
  .portrait__rows { gap: 8px; }
  /* o realce deslizante era o fundo da faixa ativa; aqui cada cartão tem o
     próprio fundo e a própria borda, então ele não tem mais o que pintar */
  .portrait__realce { display: none; }

  .prow {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "label count"
      "words words";
    align-items: center;
    gap: 12px 8px;
    padding: 13px 14px 14px 15px;
    border: 1px solid #e8e8e8;
    border-left: 3px solid var(--tone);
    border-radius: 10px;
    background: #fff;
  }
  .prow.is-active {
    border-color: var(--tone);
    box-shadow: 0 8px 22px -14px rgba(12, 12, 10, .5);
  }
  /* a frase que ainda não chegou a vez recua por TOM, não por opacidade:
     translúcida sobre o quase-branco do app ela só ficaria lavada, sem ler
     como "depois desta" */
  .prow.is-pending {
    opacity: 1;
    background: var(--paper-f5);
    /* contorno cinza-claro nos quatro lados — sem ele o cartão pendente só
       se lia pelo fundo f5, quase indistinguível do fundo da própria folha
       por trás. O filete da esquerda continua um tom mais escuro (#d4d4d4
       contra #e8e8e8): é o mesmo sinal de sempre, só que discreto. */
    border-color: #e8e8e8;
    border-left-color: #d4d4d4;
  }

  .prow__label {
    grid-area: label;
    width: auto;
    font-size: var(--fs-label);
    letter-spacing: .11em;
  }
  .prow__count { grid-area: count; font-size: var(--fs-label); letter-spacing: .06em; }
  .prow__words { grid-area: words; flex-wrap: wrap; gap: 8px; }

  .vaga {
    width: 92px;
    height: 30px;
    cursor: pointer;
  }
  .prow.is-active .vaga { border-color: var(--tone); }

  .chip { font-size: 14px; padding: 4px 4px 4px 13px; gap: 4px; }
  .chip__x { width: 20px; height: 20px; font-size: 11px; }

  /* ---- a barra de ações fica parada no pé do quadro ---- */
  .portrait__actions {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 2;
    margin: 0;
    padding: 12px 14px;
    border-top: 1px solid #e6e6e6;
    background: var(--paper-f4);
    /* o styles.css mandava o contador para uma segunda linha aqui: com o
       texto por extenso os três não cabiam. Encurtado para "5 de 8" (ver
       render() no index.html), a linha única do frame volta a caber. */
    flex-wrap: nowrap;
    justify-content: space-between;
  }
  .portrait__count {
    order: 0;
    flex: 0 1 auto;
    font-size: var(--fs-label);
    letter-spacing: .1em;
  }
  .portrait__undo,
  .portrait__next { height: var(--touch-sm); padding: 0 16px; font-size: var(--fs-label); }

  /* ==================== A GAVETA ==================== */
  .portrait__vocab {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 6;
    /* sobra do quadro o bastante para o título e a primeira frase ficarem à
       vista: a folha cobre as linhas, mas não apaga de onde ela veio */
    max-height: 74%;
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    border-top: 0;
    border-radius: 16px 16px 0 0;
    background: var(--paper);
    transform: translateY(101%);
    transition: transform .42s cubic-bezier(.22, .8, .26, 1), box-shadow .42s ease;
  }
  /* a entrada em cascata da tela também mexe em transform: se ela rodasse na
     folha, brigaria com o deslizar da gaveta pelo mesmo canal */
  .portrait.is-in .portrait__vocab { animation: none; }

  .portrait.is-banco-aberto .portrait__vocab {
    transform: none;
    /* 100%, não "none": a folha preenche exatamente o quadro FIXO (§11) e
       para aí — o que não coube na lista vira rolagem interna do
       .portrait__bank (flex:1 1 auto + min-height:0 já fazem o cabeçalho
       ficar fixo e só a lista ceder espaço). */
    max-height: 100%;
    /* o escurecimento do fundo é a PRÓPRIA sombra da folha, espalhada até
       cobrir o quadro e aparada pelo overflow do .portrait. Um elemento a
       menos no DOM, e nada que possa dessincronizar da folha: é a mesma
       transição, na mesma propriedade. */
    box-shadow: 0 -10px 30px -14px rgba(12, 12, 10, .45),
                0 0 0 100vmax rgba(12, 12, 10, .42);
  }

  .pbank__head {
    /* a regra de fora da media query zera este display para não sobrar
       cabeçalho de gaveta no desktop (§ acima); aqui precisa reafirmar, ou o
       `none` vence por ser a única declaração da propriedade na cascata —
       media query nenhuma troca "display" sozinha */
    display: block;
    position: relative;
    flex: none;
    padding: 14px 52px 18px 16px;
  }
  .pbank__grip {
    display: block;
    width: 44px;
    height: 4px;
    margin: 0 auto 20px;
    border-radius: 99px;
    background: #d9d9d9;
  }
  .pbank__eyebrow {
    font-family: var(--mono);
    font-weight: 700;
    font-size: var(--fs-label);
    letter-spacing: .11em;
    text-transform: uppercase;
    color: #737373;
  }
  /* o filete é o mesmo sinal do cartão da frase, repetido aqui: é ele que
     amarra a folha à linha que ela está preenchendo */
  /* sans, não a display: Tanker é caixa-alta única, e o frame escreve o nome
     da frase em caixa de sentença — "Sou um pouco", não "SOU UM POUCO". A
     versalete já é do rótulo acima; repeti-la aqui apagaria a diferença. */
  .pbank__alvo {
    position: relative;
    /* 5px lia como colado no rótulo acima — as duas linhas se embolavam
       numa coisa só. O dobro separa o rótulo (que é metadado) do título
       (que é a instrução), sem soltar tanto que pareçam blocos avulsos */
    margin-top: 10px;
    padding-left: 11px;
    font-family: var(--sans);
    font-weight: 800;
    font-size: 18px;
    line-height: 1.2;
    letter-spacing: -.2px;
    color: var(--banco-tom, var(--ink));
  }
  .pbank__alvo::before {
    content: "";
    position: absolute;
    left: 0;
    top: .12em;
    bottom: .12em;
    width: 3px;
    border-radius: 2px;
    background: var(--banco-tom, var(--ink));
  }
  .pbank__meta {
    margin-top: 9px;
    font-family: var(--mono);
    font-weight: 700;
    font-size: var(--fs-label);
    letter-spacing: .09em;
    text-transform: uppercase;
    color: #a3a3a3;
  }
  .pbank__close {
    position: absolute;
    /* acompanha o novo padding-top do cabeçalho — continua no mesmo eixo
       do rótulo "ESCOLHA PARA", não flutuando acima dele */
    top: 24px;
    right: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--touch-sm);
    height: var(--touch-sm);
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #f0f0ef;
    color: var(--ink);
    cursor: pointer;
    appearance: none;
  }
  .pbank__close svg { width: 17px; height: 17px; display: block; }

  /* a dica some: o cabeçalho da folha já diz para onde a palavra vai, e o ×
     de trocar vive na própria ficha, à vista, uma linha acima */
  .portrait__hint { display: none; }

  .portrait__bank {
    flex: 1 1 auto;
    min-height: 0;
    margin: 0;
    padding: 0 16px max(16px, var(--safe-b));
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    gap: 10px 8px;
    align-content: flex-start;
  }
  .bank__word { font-size: 13px; padding: 9px 14px; }
}

/* ==========================================================================
   16. O LEITOR DE PDF VOLTA PARA DENTRO DO QUADRO
   --------------------------------------------------------------------------
   Abaixo de 1360 o styles.css solta o leitor para `position: fixed; inset: 0`
   — ele virava um modal da JANELA, cobrindo a página inteira, e o que se via
   era o site sumindo atrás de um leitor de PDF que nada tinha a ver com ele.

   Ele é um modal DA MAQUETE: nasce de um botão que está dentro dela e mostra
   um documento que ela gerou. Aqui volta a ser exatamente isso — preso ao
   palco, do tamanho do quadro, com o diálogo ocupando 90% da altura dele.
   ========================================================================== */

@media (max-width: 1360px) {
  .pdfm {
    position: absolute;
    inset: 0;
    /* o quadro deixou de ter uma moldura decorativa própria em celular
       (§11, .hero__stage::before some); o palco INTEIRO é a tela, então o
       leitor cobre inset:0 dele, sem descontar respiro nenhum — descontar
       14px (resquício de quando havia moldura) deixava a faixa de cima da
       tela (arco-íris + cabeçalho) de fora do escurecimento, à mostra por
       cima do leitor. */
    height: 100%;
    padding: 0;
    align-items: center;
  }
  .pdfm__scrim {
    /* os quatro cantos, não só os de cima: a maquete (§11) já arredonda a
       base também, e o escurecimento cobre o quadro inteiro agora — segui-la
       nos quatro cantos evita o degrau quadrado onde a maquete é redonda. */
    border-radius: var(--radius-16);
  }
  /* acompanha os 900px do desktop (styles.css): as páginas são de 1200px e
     em 560 elas ficavam a 44% do nativo, menores que o texto das telas do
     produto no mesmo palco. O min() com a viewport segura telas estreitas. */
  .pdfm__dialog {
    width: calc(100% - 20px);
    max-width: min(900px, calc(100vw - 20px));
    height: 90%;
    max-height: none;
  }
}

/* ==========================================================================
   17. O RELATÓRIO EM CELULAR
   ========================================================================== */

/* a forma curta dos filtros de alinhamento existe no HTML em todas as
   larguras e só entra em cena abaixo de 768 — declarada fora da media query
   porque o padrão, aqui, é ela NÃO aparecer */
.rfilter__curto { display: none; }

@media (max-width: 768px) {
  /* ---- o menu do relatório ----
     Em 335px o "Baixar relatório" ficava espremido na ponta da terceira
     linha, com metade da largura vazia à esquerda. Sendo a ação principal da
     tela, ele toma a base inteira — é a régua do menu, e a única linha que
     não disputa espaço com nada. */
  .rnav__dl {
    flex: 1 1 100%;
    justify-content: center;
    min-height: var(--touch-sm);
  }

  /* o selo do código: `.rnav__brand` ocupa a largura toda da primeira linha
     (regra herdada de ≤1360), mas nem o título nem o selo têm flex-grow — o
     selo ficava colado no título, com o resto da linha vazio à direita.
     margin-left:auto empurra só ele até a ponta. */
  .rnav__code { margin-left: auto; }

  /* ---- as ferramentas da seção de profissões ----
     Invertidas: quem escolhe ENTRE as duas visões (Perfil / Profissões) vem
     antes de quem filtra DENTRO de uma delas. Na ordem antiga os filtros
     apareciam acima do botão que os faz existir, e em toque isso lê como se
     eles filtrassem a lista de cima.

     `column-reverse` e não uma troca no HTML: no desktop a ordem correta é a
     do documento (filtros à esquerda, seletor à direita, na mesma linha), e
     ela também é a ordem de leitura para quem navega por teclado. */
  .rtools {
    flex-direction: column-reverse;
    align-items: stretch;
    gap: 10px;
    flex-wrap: nowrap;
    /* .rtools mora dentro de .rhead--pad, que tem 18,66px de padding
       lateral PRÓPRIO — vem do desktop, onde o cabeçalho da seção é mais
       estreito que os cards abaixo dele de propósito. Aqui os cards já
       perderam essa entrada (ver .rgrid2 em ≤1360: vira coluna única, largura
       cheia), então o cabeçalho ficava mais estreito que eles, sem motivo.
       A margem negativa cancela exatamente o padding do pai e devolve a
       .rtools a mesma largura do card — mesma conta, sinal invertido. */
    margin-inline: -18.66px;
  }

  .rseg { margin-left: 0; width: 100%; }
  .rseg__btn { flex: 1 1 0; min-width: 0; height: var(--touch-sm); }
  .rseg__thumb { height: calc(100% - 4.66px); }

  /* Duas colunas em vez de uma fileira que embrulha: embrulhada, a fileira
     deixava "TODAS" sozinha numa linha e os três rótulos longos apertados na
     de cima. Em grade os quatro têm a mesma caixa, o rótulo fica à esquerda e
     o número à direita — o mesmo par que o cartão de perfil usa. */
  .rfilters {
    display: grid;
    /* minmax(0,1fr) e não 1fr: `1fr` é `minmax(auto, 1fr)`, e o `auto` deixa
       a coluna crescer até o min-content do rótulo — "ALINHAMENTO PARCIAL"
       empurrava a grade para fora do relatório em vez de ser reticado */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px;
  }
  .rfilter {
    min-width: 0;
    height: var(--touch-sm);
    padding: 0 10px;
    justify-content: space-between;
    gap: 8px;
    border: 1px solid #e4e4e7;
  }
  .rfilter.is-on { border-color: transparent; }
  /* a forma longa sai e a curta entra — as duas existem no HTML, e é a
     largura que decide qual delas está em cena */
  .rfilter__label { display: none; }
  .rfilter__curto {
    display: inline;
    font-weight: 700;
    font-size: 9.33px;
    line-height: 11.66px;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: #8a8a8a;
  }
  .rfilter.is-on .rfilter__curto { color: #fff; }
  .rfilter__n { flex: none; }
}

/* ==========================================================================
   18. O QUIZ EM CELULAR
   --------------------------------------------------------------------------
   O cartão da pergunta tem altura fixa (209,94px, do Figma) e ficava centrado
   no palco: sobrava vazio embaixo dos quatro botões. Aqui o cartão toma a
   janela inteira e a PERGUNTA + a GRADE (como bloco) ficam centradas no que
   sobra — mas cada botão mantém a própria altura de conteúdo, do tamanho de
   um alvo de toque, e não a célula inteira da grade. Esticar os botões até
   preencher o quadro foi tentado e revertido: em qualquer pergunta mais
   curta eles inchavam bem além do que um botão precisa medir, e a altura
   mudava de tela para tela — o oposto de um alvo prev isível. */

@media (max-width: 768px) {
  .mock__card { height: 100%; display: flex; flex-direction: column; justify-content: center; }
  .mock__question {
    flex: 0 0 auto;
    padding: 8px 4px 0;
  }
  /* +1pt sobre os 16px: a pergunta é o único texto de leitura da maquete e
     estava um degrau abaixo do corpo do site */
  .mock__question p { font-size: 17.33px; line-height: 25px; }

  .mock__answers {
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* a linha vale o que o conteúdo pede — não o que sobra de altura */
    grid-auto-rows: auto;
    align-items: stretch;
    gap: 10px;
    flex: 0 0 auto;
    height: auto;
    /* separada da pergunta por um vão de verdade — antes era só o padding
       de baixo da pergunta (18px), pouco para ler como dois blocos */
    margin-top: 36px;
    /* base mais estreita que o cartão: encolhida pelas laterais, ela some
       de encostar nas bordas do quadro e some de "gritar" mais largura do
       que a pergunta que a governa */
    margin-inline: 14px;
  }
  .mock__answer { height: auto; min-height: var(--touch); padding: 14px; }
}


/* ==========================================================================
   13. GRUPO DE AÇÃO EM CELULAR — o botão ocupa a largura toda
   --------------------------------------------------------------------------
   Regra do Márcio (11/09/2026), para o site inteiro: empilhados, botões de
   larguras diferentes desenham uma escada torta encostada na margem
   esquerda, e o alvo de toque do menor fica menor sem motivo — justo no
   ponto em que a página pede a ação.

   A maior parte do site já fazia isso por conta própria (.cta__buttons,
   .ip-cta__acoes, .chero__cta, .duo__cta, .espelho__acoes). O que faltava
   era o contrato morar num lugar só, e valer também para os dois grupos que
   ficavam de fora: o herói das três portas (.ip-hero__cta, em
   /instituicoes, /professores e /orientadores) e o da /iara (.ih__cta).

   Vale para GRUPO DE AÇÃO da página. NÃO vale para botão dentro de cartão,
   de tabela, de formulário ou da barra: lá a largura é do componente, e
   esticar viraria outra coisa. Por isso a lista é nominal — um seletor solto
   como `.btn` pegaria todos eles.
   ========================================================================== */
@media (max-width: 768px) {
  .ip-hero__cta,
  .ih__cta,
  .ip-cta__acoes,
  .chero__cta,
  .duo__cta,
  .espelho__acoes,
  .cta__buttons {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    /* O `width` não é enfeite: .ip-cta__acoes é item de um flex CENTRADO
       (.ip-cta), então sem largura declarada ela se mede pelo conteúdo — e
       o `width: 100%` do botão passava a resolver contra 219px em vez da
       coluna inteira. Medido em 11/09/2026, no primeiro corte desta regra. */
    width: 100%;
  }
  .ip-hero__cta > .btn,
  .ih__cta > .btn,
  .ip-cta__acoes > .btn,
  .chero__cta > .btn,
  .duo__cta > .btn,
  .espelho__acoes > .btn,
  .cta__buttons > .btn { width: 100%; }
}
