/* =============================================================================
   GranaFlow · gf-marketing.css — Design System v1.1
   -----------------------------------------------------------------------------
   FONTE ÚNICA do CSS dos componentes de marketing (namespace .gfm-*).
   Consumido pelo catálogo (design/markup/*.html) e pela landing, por <link>.

   Consumo (cópias GERADAS por `npm run design:sync`, nunca editadas à mão):
     - catálogo do DS ....... <link href="../css/gf-marketing.css"> (a fonte)
     - landing estática ..... app/landing/assets/gf-marketing.css
   Os pares estão em scripts/sync-design.mjs e travados byte a byte por
   app/src/designSync.test.js — o mesmo mecanismo que vale para gf-empty.css.

   A biblioteca React NÃO importa esta folha: o app não usa hero, planos nem
   rodapé. A única peça de marketing que ele consome é o SELO, e por isso o selo
   tem folha própria — design/css/gf-seal.css (ver seção 4).

   Regras de autoria (design/README.md, "Admitindo um componente novo"):
     1. Zero cor literal. Tudo via var(--gf-*) / var(--r-*) / var(--sp-*) / var(--fs-*).
     2. Nenhum estilo em JS. Prop do React mapeia 1:1 para modificador de classe.
     3. O único inline permitido é custom property de INSTÂNCIA (dado, não estilo):
        style="--gfm-hero-media:url(...)" · style="--gfm-meter:62%".
     4. Verde e vermelho são exclusivos de receita/despesa. Marketing comunica
        confiança em navy + azul + ouro. Texto sobre ouro é sempre navy.

   Dependência: os tokens do PR-1 (design/tokens/*.md → app/src/theme.css).

   Índice
     0. Primitivas compartilhadas (CTA, skeleton, utilitários)
     1. .gfm-section · .gfm-sechead · .gfm-grid
     2. .gfm-hero
     3. .gfm-feature
     4. .gfm-trust (o selo mora em design/css/gf-seal.css)
     5. .gfm-quote · .gfm-counter
     6. .gfm-plan
     7. .gfm-footer
     8. .gfm-demobar
     9. .gfm-siteheader · .gfm-skiplink
    10. .gfm-compare
    11. .gfm-consent
   ========================================================================== */


/* =============================================================================
   0. PRIMITIVAS COMPARTILHADAS
   ========================================================================== */

/* Contexto "sobre marca": qualquer superfície navy marca a si mesma com esta
   classe. É o gancho que troca eyebrow, anel de foco e cor de link sem que cada
   componente precise saber em que fundo está. */
.gfm-on-brand { color: var(--gf-on-brand); }
.gfm-on-brand a { color: var(--gf-on-brand-accent); }

/* Só para leitor de tela. */
.gfm-sr {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- CTA (gêmeo estático do <Button> do app) --------------------------------
   A landing não carrega React; precisa de um botão em CSS puro. Variantes e
   estados espelham <Button> deliberadamente — quem mudar um, muda o outro. */
.gfm-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  font-family: inherit;
  font-size: var(--fs-lg);
  font-weight: var(--fw-semi);
  line-height: 1.2;
  min-height: 48px;                 /* alvo de toque */
  padding: var(--sp-5) var(--sp-8);
  border: none;
  border-radius: var(--r-sm);
  text-decoration: none;
  cursor: pointer;
  transition:
    transform var(--gf-dur-fast) var(--gf-ease),
    box-shadow var(--gf-dur) var(--gf-ease),
    background-color var(--gf-dur) var(--gf-ease);
}
.gfm-cta svg { width: 18px; height: 18px; flex: none; }

/* Ouro = CTA/prosperidade. Texto SEMPRE navy — nunca branco. */
.gfm-cta--gold {
  background: var(--gf-gold);
  color: var(--gf-brand-navy);
  font-weight: var(--fw-bold);
  box-shadow: var(--shadow-gold);
}
/* Azul = marca/ação. */
.gfm-cta--brand {
  background: var(--gf-blue);
  color: var(--gf-on-brand);
  box-shadow: var(--shadow-brand);
}
/* Secundário sobre superfície de marca. */
.gfm-cta--outline {
  background: transparent;
  color: var(--gf-on-brand);
  border: 1.5px solid var(--gf-on-brand-line);
  padding: calc(var(--sp-5) - 1.5px) calc(var(--sp-8) - 1.5px);
}
/* Secundário sobre superfície clara. */
.gfm-cta--quiet {
  background: var(--gf-surface);
  color: var(--gf-navy);
  border: 1.5px solid var(--gf-line-strong);
  padding: calc(var(--sp-5) - 1.5px) calc(var(--sp-8) - 1.5px);
}
.gfm-cta--ghost {
  background: transparent;
  color: var(--gf-blue);
  box-shadow: none;
}

.gfm-cta--sm { font-size: var(--fs-md); min-height: 38px; padding: var(--sp-3) var(--sp-7); border-radius: var(--r-xs); }
.gfm-cta--lg { font-size: 17px; min-height: 56px; padding: var(--sp-7) calc(var(--sp-8) + var(--sp-2)); border-radius: var(--r-md); }
.gfm-cta--block { width: 100%; }

@media (hover: hover) {
  .gfm-cta:hover { transform: translateY(-1px); }
  .gfm-cta--gold:hover  { box-shadow: var(--shadow-gold), var(--shadow-md); }
  .gfm-cta--brand:hover { box-shadow: var(--shadow-brand), var(--shadow-md); }
  .gfm-cta--outline:hover { background: var(--gf-on-brand-line); }
  .gfm-cta--quiet:hover { background: var(--gf-mist); }
  .gfm-cta--ghost:hover { background: var(--gf-blue-soft); }
}
.gfm-cta:active { transform: scale(.98); }
.gfm-cta:focus-visible { outline: none; box-shadow: var(--gf-focus-ring); }
/* O anel azul é invisível sobre navy — bug de a11y latente, resolvido aqui. */
.gfm-on-brand .gfm-cta:focus-visible,
.gfm-section--on-brand .gfm-cta:focus-visible,
.gfm-hero .gfm-cta:focus-visible,
.gfm-footer .gfm-cta:focus-visible,
.gfm-demobar .gfm-cta:focus-visible { box-shadow: var(--gf-focus-ring-on-brand); }

/* .gfm-on-brand a { color: on-brand-accent } (link sobre navy) tem especificidade
   0,1,1 e vencia o color do CTA (0,1,0): o texto do CTA de ouro virava azul sobre
   qualquer superfície de marca — quebra do invariante "texto sobre ouro em navy".
   Aqui a cor de cada variante é reafirmada com 0,2,1, acima do link genérico. */
.gfm-on-brand a.gfm-cta--gold    { color: var(--gf-brand-navy); }
.gfm-on-brand a.gfm-cta--outline { color: var(--gf-on-brand); }
.gfm-on-brand a.gfm-cta--brand   { color: var(--gf-on-brand); }
.gfm-on-brand a.gfm-cta--quiet   { color: var(--gf-navy); }
.gfm-on-brand a.gfm-cta--ghost   { color: var(--gf-blue); }

.gfm-cta[aria-disabled="true"],
.gfm-cta:disabled {
  background: var(--gf-chip);
  color: var(--gf-disabled);
  border-color: transparent;
  box-shadow: none;
  cursor: not-allowed;
  transform: none;
}

/* Carregando: largura travada pelo conteúdo original, rótulo some, spinner entra. */
.gfm-cta[data-state="loading"] { pointer-events: none; position: relative; color: transparent; }
.gfm-cta[data-state="loading"]::after {
  content: "";
  position: absolute;
  inset: 50% auto auto 50%;
  width: 18px; height: 18px;
  margin: -9px 0 0 -9px;
  border-radius: var(--r-pill);
  border: 2.4px solid currentColor;
  border-top-color: transparent;
  color: var(--gf-brand-navy);
  animation: gfm-spin 700ms linear infinite;
}
.gfm-cta--brand[data-state="loading"]::after,
.gfm-cta--outline[data-state="loading"]::after { color: var(--gf-on-brand); }
.gfm-cta--quiet[data-state="loading"]::after,
.gfm-cta--ghost[data-state="loading"]::after { color: var(--gf-blue); }
@keyframes gfm-spin { to { transform: rotate(360deg); } }

/* ---- Skeleton (estado "carregando" de qualquer bloco) ----------------------- */
.gfm-skel {
  position: relative;
  overflow: hidden;
  color: transparent !important;
  background: var(--gf-track);
  border-radius: var(--r-xs);
  user-select: none;
  pointer-events: none;
}
.gfm-skel > * { visibility: hidden; }
.gfm-skel::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--gf-surface), transparent);
  opacity: .45;
  animation: gfm-shimmer 1.4s var(--gf-ease) infinite;
}
.gfm-skel--line   { height: 12px; }
.gfm-skel--title  { height: 20px; border-radius: var(--r-xs); }
.gfm-skel--block  { height: 100%; border-radius: var(--r-md); }
.gfm-skel--circle { border-radius: var(--r-pill); }
.gfm-skel--w40 { width: 40%; }
.gfm-skel--w60 { width: 60%; }
.gfm-skel--w80 { width: 80%; }
@keyframes gfm-shimmer { to { transform: translateX(100%); } }

/* Qualquer raiz .gfm-* em carregamento perde interatividade. */
[data-state="loading"] { cursor: progress; }

@media (prefers-reduced-motion: reduce) {
  .gfm-cta { transition: none; }
  .gfm-cta:hover, .gfm-cta:active { transform: none; }
  .gfm-cta[data-state="loading"]::after,
  .gfm-skel::after { animation: none; }
  .gfm-skel::after { opacity: .2; transform: none; }
}


/* =============================================================================
   1. SEÇÃO — .gfm-section · .gfm-sechead · .gfm-grid
   O ritmo vertical da página. Nenhum bloco inventa o próprio espaçamento.
   ========================================================================== */

.gfm-section {
  padding-block: var(--gf-section-y);
  background: var(--gf-mist-deep);
  color: var(--gf-navy);
  scroll-margin-block-start: 72px;   /* header sticky + banner de demo */
}
.gfm-section--on-mist    { background: var(--gf-mist-deep); }
.gfm-section--on-surface { background: var(--gf-surface); }
.gfm-section--on-brand   { background: var(--gf-brand-navy); color: var(--gf-on-brand); }
.gfm-section--on-brand-grad { background: var(--gf-brand-navy-grad); color: var(--gf-on-brand); }

.gfm-section--tight { padding-block: calc(var(--gf-section-y) * .6); }
.gfm-section--roomy { padding-block: calc(var(--gf-section-y) * 1.4); }

/* Estado VAZIO: seção sem conteúdo não renderiza (regra do DS, #273).
   Não é "esconder por CSS" — é o contrato: o gerador marca data-state="empty"
   e a seção some inteira, sem deixar um buraco de padding na página. */
.gfm-section[data-state="empty"] { display: none; }

.gfm-section__inner {
  max-width: var(--gf-container);
  margin-inline: auto;
  padding-inline: var(--gf-gutter);
}

.gfm-sechead {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  max-width: var(--gf-measure);
  margin-bottom: var(--sp-8);
}
.gfm-sechead__eyebrow {
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gf-blue);
}
.gfm-sechead__title {
  font-size: var(--gf-fs-h2);
  font-weight: var(--fw-bold);
  letter-spacing: -.02em;
  line-height: 1.2;
  color: inherit;
}
.gfm-sechead__deck {
  font-size: var(--gf-fs-lead);
  font-weight: var(--fw-regular);
  line-height: 1.55;
  color: var(--gf-text);
}
/* Seção sem deck: o gap fecha sozinho (flex gap), sem buraco. */
.gfm-sechead--lead .gfm-sechead__title { font-size: var(--gf-fs-h1); }

.gfm-section--on-brand .gfm-sechead__eyebrow,
.gfm-section--on-brand-grad .gfm-sechead__eyebrow { color: var(--gf-on-brand-accent); }
.gfm-section--on-brand .gfm-sechead__deck,
.gfm-section--on-brand-grad .gfm-sechead__deck { color: var(--gf-on-brand-muted); }

/* Cabeçalho centralizado: só do desktop pra cima. Em coluna estreita, texto
   centralizado prejudica a leitura. */
@media (min-width: 768px) {
  .gfm-sechead--center { margin-inline: auto; text-align: center; }
}

.gfm-section__foot {
  margin-top: var(--sp-8);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-4);
}
@media (min-width: 768px) {
  .gfm-sechead--center ~ .gfm-section__foot { justify-content: center; }
}

/* ---- Grade ---- */
.gfm-grid { display: grid; gap: var(--sp-6); grid-template-columns: 1fr; }
.gfm-grid--auto { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }

@media (min-width: 600px) {
  .gfm-grid--cols-2,
  .gfm-grid--cols-3,
  .gfm-grid--cols-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 960px) {
  .gfm-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
  .gfm-grid--cols-4 { grid-template-columns: repeat(4, 1fr); }
}

/* Rail: scroll-snap horizontal no mobile, grade no desktop. Sem JS. */
.gfm-grid--rail {
  grid-auto-flow: column;
  grid-auto-columns: minmax(260px, 78%);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gf-gutter);
  margin-inline: calc(var(--gf-gutter) * -1);
  padding-inline: var(--gf-gutter);
  padding-bottom: var(--sp-3);
  -webkit-overflow-scrolling: touch;
}
.gfm-grid--rail > * { scroll-snap-align: start; }
@media (min-width: 768px) {
  .gfm-grid--rail {
    grid-auto-flow: row;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-columns: auto;
    overflow-x: visible;
    margin-inline: 0;
    padding-inline: 0;
  }
}

/* Carregando: o cabeçalho vira skeleton, a grade mantém a altura. */
.gfm-section[data-state="loading"] .gfm-grid { opacity: .6; }


/* =============================================================================
   2. HERO — .gfm-hero
   Os 3 primeiros segundos do único ponto de contato público.
   ========================================================================== */

.gfm-hero {
  position: relative;
  overflow: hidden;
  background: var(--gf-brand-navy-grad);
  color: var(--gf-on-brand);
  padding-block: var(--gf-section-y);
}
.gfm-hero__inner {
  position: relative;
  z-index: 1;
  max-width: var(--gf-container);
  margin-inline: auto;
  padding-inline: var(--gf-gutter);
  display: grid;
  gap: var(--sp-8);
}
/* A "bolha de ouro" — motivo recorrente do DS. Decorativa: aria-hidden. */
.gfm-hero__veil {
  position: absolute;
  top: -80px;
  right: -60px;
  width: 320px;
  height: 320px;
  border-radius: var(--r-pill);
  background: var(--gf-gold-veil);
  pointer-events: none;
}

.gfm-hero__eyebrow {
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gf-on-brand-accent);
  margin-bottom: var(--sp-4);
}
.gfm-hero__title {
  font-size: var(--gf-fs-display);
  font-weight: var(--fw-black);
  letter-spacing: -.03em;
  line-height: 1.08;
  max-width: var(--gf-measure);
  color: var(--gf-on-brand);
}
.gfm-hero__deck {
  margin-top: var(--sp-6);
  font-size: var(--gf-fs-lead);
  font-weight: var(--fw-regular);
  line-height: 1.55;
  max-width: 46ch;
  color: var(--gf-on-brand-muted);
}
.gfm-hero__actions {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  margin-top: var(--sp-8);
}
/* Microcopy de REDUÇÃO DE RISCO, logo sob os CTAs (#266).
   Vive fora do botão de propósito: enfiar "grátis — sem cartão — sem senha" no
   rótulo alonga o alvo de toque no telefone e enterra a informação no meio de
   uma frase-botão. Linha própria embaixo lê melhor e não compete com a ação.
   Só afirmação VERIFICÁVEL entra aqui — é o lugar onde uma promessa falsa custa
   mais caro. */
.gfm-hero__note {
  margin-top: var(--sp-4);
  font-size: var(--fs-md);
  color: var(--gf-on-brand-muted);
}
/* Sobre superfície clara (hero de página interna, seção de fechamento). */
.gfm-hero__note--on-surface { color: var(--gf-muted); }

.gfm-hero__proof { margin-top: var(--sp-7); }

/* Mídia — é o LCP. Dimensões explícitas no HTML, fetchpriority="high". */
.gfm-hero__media { position: relative; }
.gfm-hero__media img,
.gfm-hero__media video {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
}
.gfm-hero__media--bare img,
.gfm-hero__media--bare video {
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-xl);
  aspect-ratio: 4 / 5;
  object-fit: cover;
}
/* Moldura de aparelho — exatamente o frame que o DS já usa nas telas. */
.gfm-hero__media--device {
  max-width: 300px;
  margin-inline: auto;
  background: var(--gf-brand-navy);
  border-radius: var(--r-device);
  padding: 10px;
  box-shadow: var(--shadow-xl);
}
.gfm-hero__media--device img,
.gfm-hero__media--device video {
  border-radius: var(--r-device-screen);
  aspect-ratio: 300 / 620;
  object-fit: cover;
  background: var(--gf-mist);
}
/* Estado SEM MÍDIA: o slot colapsa. O hero não vira uma caixa vazia. */
.gfm-hero--media-none .gfm-hero__media,
.gfm-hero__media:empty { display: none; }

.gfm-hero--compact { padding-block: calc(var(--gf-section-y) * .55); }
.gfm-hero--compact .gfm-hero__title { font-size: var(--gf-fs-h1); }

/* Estado CARREGANDO: o texto já está no HTML (é estático); só a mídia espera. */
.gfm-hero[data-state="loading"] .gfm-hero__media {
  background: var(--gf-brand-navy);
  border-radius: var(--r-xl);
  min-height: 240px;
}

@media (min-width: 600px) {
  .gfm-hero__actions { flex-direction: row; flex-wrap: wrap; align-items: center; }
  .gfm-hero__actions .gfm-cta { width: auto; }
}
@media (min-width: 960px) {
  .gfm-hero--media-side .gfm-hero__inner {
    grid-template-columns: 1.05fr 1fr;
    align-items: center;
    gap: calc(var(--sp-8) * 2);
  }
  .gfm-hero--media-side .gfm-hero__media--bare img,
  .gfm-hero--media-side .gfm-hero__media--bare video { aspect-ratio: 16 / 10; }
}

@media (hover: hover) {
  .gfm-hero__actions .gfm-cta:hover { box-shadow: var(--shadow-gold), var(--shadow-xl); }
  .gfm-hero__actions .gfm-cta--outline:hover { box-shadow: none; }
}


/* =============================================================================
   3. FEATURE — .gfm-feature
   Unidade de conteúdo das seções "o que o GranaFlow faz".
   ========================================================================== */

.gfm-feature {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: clamp(16px, 4vw, 22px);
  background: var(--gf-surface);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  transition: box-shadow var(--gf-dur) var(--gf-ease), transform var(--gf-dur) var(--gf-ease);
}
.gfm-feature--flat { background: transparent; box-shadow: none; padding-inline: 0; }
.gfm-feature--horizontal { flex-direction: row; align-items: flex-start; gap: var(--sp-5); }
.gfm-feature--horizontal .gfm-feature__body-wrap { flex: 1; }
.gfm-feature--featured { gap: var(--sp-6); }
@media (min-width: 600px) {
  .gfm-feature--featured { grid-column: span 2; }
}

.gfm-feature__tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px; height: 46px;
  flex: none;
  border-radius: var(--r-sm);
  background: var(--gf-mist);
  color: var(--gf-blue);
}
.gfm-feature__tile svg {
  width: 22px; height: 22px;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.gfm-feature--tile-blue .gfm-feature__tile { background: var(--gf-mist); color: var(--gf-blue); }
.gfm-feature--tile-gold .gfm-feature__tile { background: var(--gf-gold-soft); color: var(--gf-gold-deep); }
.gfm-feature--tile-navy .gfm-feature__tile { background: var(--gf-brand-navy-grad); color: var(--gf-on-brand); }

/* PROIBIDO — registrado como proibido, não só combinado de boca:
   os modificadores "tile-income" e "tile-expense" NÃO existem e não vão existir.
   Verde e vermelho não decoram feature; são exclusivos de receita/despesa.
   (Escrito sem o ponto de propósito: o teste de contrato varre seletores, e um
   seletor comentado aqui apareceria como classe definida-e-não-usada.) */

.gfm-feature__title {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  line-height: 1.3;
  color: var(--gf-navy);
}
.gfm-feature__body {
  font-size: var(--fs-lg);
  line-height: 1.55;
  color: var(--gf-text);
}
.gfm-feature__link {
  font-size: var(--fs-md);
  font-weight: var(--fw-semi);
  color: var(--gf-blue);
  text-decoration: none;
  align-self: flex-start;
}
@media (hover: hover) { .gfm-feature__link:hover { text-decoration: underline; } }

/* Card inteiro clicável: o <a> real envolve só o título (o leitor de tela anuncia
   um destino, não um parágrafo) e o link é esticado por pseudo-elemento. */
.gfm-feature--linked .gfm-feature__title a { color: inherit; text-decoration: none; }
.gfm-feature--linked .gfm-feature__title a::after { content: ""; position: absolute; inset: 0; }
.gfm-feature--linked:focus-within { box-shadow: var(--shadow-card), var(--gf-focus-ring); }
.gfm-feature--linked .gfm-feature__title a:focus-visible { outline: none; }
@media (hover: hover) {
  .gfm-feature--linked:hover { box-shadow: var(--shadow-float); transform: translateY(-2px); }
}
.gfm-feature--linked:active { transform: translateY(0); }

/* Sobre navy */
.gfm-section--on-brand .gfm-feature,
.gfm-section--on-brand-grad .gfm-feature {
  background: var(--gf-on-brand-line);
  box-shadow: none;
}
.gfm-section--on-brand .gfm-feature__title { color: var(--gf-on-brand); }
.gfm-section--on-brand .gfm-feature__body  { color: var(--gf-on-brand-muted); }
.gfm-section--on-brand .gfm-feature__link  { color: var(--gf-on-brand-accent); }

/* Carregando */
.gfm-feature[data-state="loading"] { pointer-events: none; }
.gfm-feature[data-state="loading"] .gfm-feature__tile { background: var(--gf-track); color: transparent; }

@media (prefers-reduced-motion: reduce) {
  .gfm-feature { transition: box-shadow var(--gf-dur) var(--gf-ease); }
  .gfm-feature--linked:hover { transform: none; }
}


/* =============================================================================
   4. SEGURANÇA — .gfm-trust  (selo: design/css/gf-seal.css)
   Cada afirmação é de ARQUITETURA, nunca de CERTIFICAÇÃO. Ícones em ouro ou
   branco sobre navy — NUNCA verde (o reflexo "cadeado verde" quebra a
   invariante: verde é receita, ponto).
   ========================================================================== */

.gfm-trust { display: flex; flex-direction: column; gap: var(--sp-8); }

.gfm-trust__items { display: grid; gap: var(--sp-7); grid-template-columns: 1fr; }
@media (min-width: 768px) {
  .gfm-trust__items { grid-template-columns: repeat(3, 1fr); gap: var(--sp-8); }
}

.gfm-trust__item { display: flex; gap: var(--sp-5); align-items: flex-start; }
@media (min-width: 768px) {
  .gfm-trust__item { flex-direction: column; gap: var(--sp-4); }
}
.gfm-trust--horizontal .gfm-trust__item { flex-direction: row; }

.gfm-trust__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px;
  flex: none;
  border-radius: var(--r-icon);
  background: var(--gf-gold-veil);
  color: var(--gf-gold);
}
.gfm-trust__icon svg { width: 20px; height: 20px; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

.gfm-trust__title { font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--gf-on-brand); }
.gfm-trust__body  { font-size: var(--fs-base); line-height: 1.5; color: var(--gf-on-brand-muted); margin-top: var(--sp-2); }

/* Variante clara — a única peça que o app reaproveita (tela de Criptografia). */
.gfm-trust--on-surface .gfm-trust__icon { background: var(--gf-gold-soft); color: var(--gf-gold-deep); }
.gfm-trust--on-surface .gfm-trust__title { color: var(--gf-navy); }
.gfm-trust--on-surface .gfm-trust__body  { color: var(--gf-text); }

/* Detalhe técnico em <details>/<summary> — a landing não carrega JS. */
.gfm-trust__detail {
  border-top: 1px solid var(--gf-on-brand-line);
  padding-top: var(--sp-6);
}
.gfm-trust--on-surface .gfm-trust__detail { border-top-color: var(--gf-line); }
.gfm-trust__detail > summary {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  list-style: none;
  cursor: pointer;
  font-size: var(--fs-base);
  font-weight: var(--fw-semi);
  color: var(--gf-on-brand);
  padding: var(--sp-3) 0;
  border-radius: var(--r-xs);
}
.gfm-trust--on-surface .gfm-trust__detail > summary { color: var(--gf-navy); }
.gfm-trust__detail > summary::-webkit-details-marker { display: none; }
.gfm-trust__detail > summary::before {
  content: "";
  width: 8px; height: 8px;
  flex: none;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--gf-dur) var(--gf-ease);
}
.gfm-trust__detail[open] > summary::before { transform: rotate(45deg); }
.gfm-trust__detail > summary:focus-visible { outline: none; box-shadow: var(--gf-focus-ring-on-brand); }
.gfm-trust--on-surface .gfm-trust__detail > summary:focus-visible { box-shadow: var(--gf-focus-ring); }
.gfm-trust__detail-body {
  font-size: var(--fs-base);
  line-height: 1.6;
  color: var(--gf-on-brand-muted);
  max-width: var(--gf-measure);
  padding-bottom: var(--sp-4);
}
.gfm-trust--on-surface .gfm-trust__detail-body { color: var(--gf-text); }

.gfm-trust__note { font-size: var(--fs-md); color: var(--gf-on-brand-muted); }
.gfm-trust--on-surface .gfm-trust__note { color: var(--gf-muted); }

/* ---- Selo -------------------------------------------------------------------
   O SELO NÃO MORA AQUI: .gfm-seal · .gfm-seal-strip vivem em
   design/css/gf-seal.css, folha própria, porque o app também os consome (#267)
   — cadastro e Configurações → Criptografia. Trazer estes 45 KB para a
   biblioteca React só para usar o selo colocaria hero, planos e rodapé no boot
   do app. Quem usa o selo carrega as DUAS folhas (é o que os HTML fazem).
   Mesma decisão do gf-empty.css; ver o cabeçalho do gf-seal.css. */

/* Carregando */
.gfm-trust[data-state="loading"] .gfm-trust__icon { background: var(--gf-track); color: transparent; }

@media (prefers-reduced-motion: reduce) {
  .gfm-trust__detail > summary::before { transition: none; }
}


/* =============================================================================
   5. PROVA SOCIAL — .gfm-quote · .gfm-counter
   Prova social fabricada destrói a credibilidade que a seção de segurança
   acabou de construir. Regras de renderização abaixo são estruturais.
   ========================================================================== */

.gfm-quote {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
  padding: clamp(18px, 4vw, 24px);
  background: var(--gf-surface);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}
.gfm-quote--on-brand {
  background: var(--gf-on-brand-line);
  box-shadow: none;
}
.gfm-quote--compact { gap: var(--sp-4); padding: var(--sp-6); }

.gfm-quote__mark {
  font-family: var(--font-num);
  font-size: 34px;
  font-weight: var(--fw-bold);
  line-height: .8;
  color: var(--gf-gold);
}
.gfm-quote__text {
  font-size: var(--fs-xl);
  line-height: 1.55;
  color: var(--gf-navy);
}
.gfm-quote--on-brand .gfm-quote__text { color: var(--gf-on-brand); }
.gfm-quote--featured .gfm-quote__text { font-size: var(--gf-fs-lead); }

.gfm-quote__foot { display: flex; align-items: center; gap: var(--sp-4); margin-top: auto; }
.gfm-quote__avatar {
  width: 44px; height: 44px;
  flex: none;
  border-radius: var(--r-pill);
  object-fit: cover;
  background: var(--gf-mist);
}
/* Fallback de iniciais é OBRIGATÓRIO — é o estado padrão quando não há
   consentimento de imagem, não uma degradação. */
.gfm-quote__avatar--initials {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  color: var(--gf-navy);
  background: var(--gf-mist);
  letter-spacing: .02em;
}
.gfm-quote--on-brand .gfm-quote__avatar--initials { background: var(--gf-on-brand-line); color: var(--gf-on-brand); }

.gfm-quote__name { font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--gf-navy); }
.gfm-quote--on-brand .gfm-quote__name { color: var(--gf-on-brand); }
/* Granularidade grossa: "casal, RJ" — nunca sobrenome + cidade + profissão. */
.gfm-quote__meta { font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--gf-muted); }
.gfm-quote--on-brand .gfm-quote__meta { color: var(--gf-on-brand-muted); }

/* Estado sem consentimento registrado: o depoimento NÃO renderiza.
   O gerador marca data-consent="missing" e o item some — a regra é de DS,
   não de copy, porque é requisito de LGPD. */
.gfm-quote[data-consent="missing"] { display: none; }

/* Carregando */
.gfm-quote[data-state="loading"] .gfm-quote__avatar { background: var(--gf-track); }

/* ---- Contador --------------------------------------------------------------
   NUNCA animar contagem crescente: parece marketing barato e conflita com
   reduced-motion. Números reais, com data-asof visível. */
.gfm-counter { display: grid; gap: var(--sp-7); grid-template-columns: repeat(3, 1fr); }
.gfm-counter__item { display: flex; flex-direction: column; gap: var(--sp-2); }
.gfm-counter--with-icon .gfm-counter__item { gap: var(--sp-3); }
.gfm-counter__icon { color: var(--gf-gold); width: 22px; height: 22px; }
.gfm-counter__value {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-bold);
  font-size: clamp(26px, 7vw, 34px);
  letter-spacing: -.02em;
  color: var(--gf-navy);
}
.gfm-counter__label { font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--gf-muted); line-height: 1.4; }
.gfm-counter__asof  { font-size: var(--fs-xs); color: var(--gf-muted); margin-top: var(--sp-4); }

.gfm-on-brand .gfm-counter__value,
.gfm-section--on-brand .gfm-counter__value,
.gfm-hero .gfm-counter__value { color: var(--gf-on-brand); }
.gfm-on-brand .gfm-counter__label,
.gfm-on-brand .gfm-counter__asof,
.gfm-section--on-brand .gfm-counter__label,
.gfm-section--on-brand .gfm-counter__asof,
.gfm-hero .gfm-counter__label,
.gfm-hero .gfm-counter__asof { color: var(--gf-on-brand-muted); }

/* Dentro do hero: valores menores, em linha. */
.gfm-counter--inline { display: flex; flex-wrap: wrap; gap: var(--sp-7); }
.gfm-counter--inline .gfm-counter__value { font-size: var(--fs-2xl); }
.gfm-counter--inline .gfm-counter__label { font-size: var(--fs-sm); }

.gfm-counter--band {
  padding: var(--sp-8) 0;
  border-block: 1px solid var(--gf-line);
}
.gfm-section--on-brand .gfm-counter--band { border-block-color: var(--gf-on-brand-line); }

/* Carregando */
.gfm-counter[data-state="loading"] .gfm-counter__value { color: transparent; background: var(--gf-track); border-radius: var(--r-xs); }


/* =============================================================================
   6. PLANOS — .gfm-plan
   A lista de features é DADO (design/data/plans.json), não markup: a landing e
   o React leem o MESMO arquivo. Os ✓ são AZUIS — verde é receita.
   ========================================================================== */

.gfm-plans { display: grid; gap: var(--sp-6); grid-template-columns: 1fr; align-items: start; }
@media (min-width: 768px) { .gfm-plans { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 960px) { .gfm-plans--3 { grid-template-columns: repeat(3, 1fr); } }

.gfm-plan {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
  padding: clamp(20px, 4vw, 26px);
  background: var(--gf-surface);
  border: 1.5px solid var(--gf-line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-card);
}
.gfm-plan--recommended {
  border-color: var(--gf-gold);
  box-shadow: var(--shadow-float);
}
.gfm-plan--compact { gap: var(--sp-5); padding: var(--sp-7); }

/* Faixa "Recomendado": ouro claro com texto NAVY. */
.gfm-plan__ribbon {
  position: absolute;
  top: 0; left: 50%;
  transform: translate(-50%, -50%);
  background: var(--gf-gold-soft-strong);
  color: var(--gf-navy);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: var(--sp-2) var(--sp-5);
  border-radius: var(--r-pill);
  white-space: nowrap;
}

.gfm-plan__name    { font-size: var(--fs-xl); font-weight: var(--fw-bold); color: var(--gf-navy); }
.gfm-plan__tagline { font-size: var(--fs-base); color: var(--gf-text); line-height: 1.5; margin-top: var(--sp-2); }

.gfm-plan__price { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--sp-2); }
.gfm-plan__amount {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-display);
  font-weight: var(--fw-bold);
  letter-spacing: -.02em;
  color: var(--gf-navy);
}
.gfm-plan__period { font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--gf-muted); }

.gfm-plan__features { list-style: none; display: flex; flex-direction: column; gap: var(--sp-4); }
.gfm-plan__feat {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-4);
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--gf-text);
}
.gfm-plan__feat-icon { width: 18px; height: 18px; flex: none; margin-top: 2px; }
/* Incluído: ✓ AZUL. Confiança não é verde. */
.gfm-plan__feat[data-level="included"] .gfm-plan__feat-icon { color: var(--gf-blue); }
/* Limitado: ouro escuro, peso alto (ouro como texto em fundo claro). */
.gfm-plan__feat[data-level="limited"]  .gfm-plan__feat-icon { color: var(--gf-gold-deep); }
.gfm-plan__feat[data-level="limited"]  { font-weight: var(--fw-medium); }
/* Ausente: neutro apagado, jamais vermelho. */
.gfm-plan__feat[data-level="absent"]   .gfm-plan__feat-icon { color: var(--gf-disabled); }
.gfm-plan__feat[data-level="absent"]   { color: var(--gf-muted); }
.gfm-plan__feat-note { display: block; font-size: var(--fs-sm); color: var(--gf-muted); }

.gfm-plan__cta { margin-top: auto; }
.gfm-plan__note { font-size: var(--fs-sm); color: var(--gf-muted); text-align: center; }

/* Estado VAZIO: plano sem features declaradas não vira card vazio — some. */
.gfm-plan[data-state="empty"] { display: none; }
/* Estado CARREGANDO: mantém a altura para não empurrar a página. */
.gfm-plan[data-state="loading"] { pointer-events: none; min-height: 380px; }


/* =============================================================================
   7. RODAPÉ — .gfm-footer
   ========================================================================== */

.gfm-footer {
  background: var(--gf-brand-navy);
  color: var(--gf-on-brand);
  padding-block: var(--sp-8) var(--sp-7);
}
.gfm-footer__inner {
  max-width: var(--gf-container);
  margin-inline: auto;
  padding-inline: var(--gf-gutter);
  display: grid;
  gap: var(--sp-8);
}
.gfm-footer__brand { display: flex; flex-direction: column; gap: var(--sp-4); max-width: 34ch; }
.gfm-footer__lockup {
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-2xl);
  font-weight: var(--fw-black);
  letter-spacing: -.02em;
  color: var(--gf-on-brand);
  text-decoration: none;
}
/* Margem no ícone, não `gap` no container: `gap` separaria "Grana" de <em>Flow</em>
   (itens flex distintos) e quebraria a marca em "Grana Flow". Também cobre a
   variante reduzida do rodapé, que não tem ícone. */
.gfm-footer__lockup svg { width: 30px; height: 30px; margin-inline-end: var(--sp-3); }
/* O "Flow" do lockup sobre navy. */
.gfm-footer__lockup em { font-style: normal; color: var(--gf-on-brand-accent); }
.gfm-footer__tagline { font-size: var(--fs-base); line-height: 1.55; color: var(--gf-on-brand-muted); }

.gfm-footer__cols { display: grid; gap: var(--sp-7); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 768px) {
  .gfm-footer__inner { grid-template-columns: 1.2fr 2fr; gap: calc(var(--sp-8) * 1.5); }
  .gfm-footer__cols  { grid-template-columns: repeat(3, 1fr); }
}
.gfm-footer__col { display: flex; flex-direction: column; gap: var(--sp-3); }
.gfm-footer__coltitle {
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gf-on-brand-accent);
  margin-bottom: var(--sp-1);
}
.gfm-footer__link {
  font-size: var(--fs-base);
  color: var(--gf-on-brand-muted);
  text-decoration: none;
  border-radius: var(--r-xs);
  padding-block: var(--sp-1);
}
@media (hover: hover) { .gfm-footer__link:hover { color: var(--gf-on-brand); } }
.gfm-footer__link:focus-visible { outline: none; box-shadow: var(--gf-focus-ring-on-brand); }

.gfm-footer__seals { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

.gfm-footer__legal {
  max-width: var(--gf-container);
  margin: var(--sp-8) auto 0;
  padding: var(--sp-6) var(--gf-gutter) 0;
  border-top: 1px solid var(--gf-on-brand-line);
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--gf-on-brand-muted);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  justify-content: space-between;
}


/* =============================================================================
   8. BANNER DE DEMO — .gfm-demobar
   Consumido nos dois mundos: o shell da demo pública e o app em modo demo.
   ========================================================================== */

.gfm-demobar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--gf-gutter);
  background: var(--gf-brand-navy);
  color: var(--gf-on-brand);
  font-size: var(--fs-base);
}
.gfm-demobar--sticky { position: sticky; top: 0; z-index: 30; box-shadow: var(--shadow-md); }
.gfm-demobar--inline { border-radius: var(--r-md); padding-inline: var(--sp-6); }

.gfm-demobar__dot {
  width: 8px; height: 8px;
  flex: none;
  border-radius: var(--r-pill);
  background: var(--gf-gold);
}
.gfm-demobar__text { flex: 1; min-width: 12ch; line-height: 1.4; }
.gfm-demobar__text strong { font-weight: var(--fw-bold); }
.gfm-demobar__hint { display: block; font-size: var(--fs-sm); color: var(--gf-on-brand-muted); }
.gfm-demobar__actions { display: flex; align-items: center; gap: var(--sp-3); }

.gfm-demobar__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  flex: none;
  border: none;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--gf-on-brand-muted);
  cursor: pointer;
}
@media (hover: hover) { .gfm-demobar__close:hover { background: var(--gf-on-brand-line); color: var(--gf-on-brand); } }
.gfm-demobar__close:focus-visible { outline: none; box-shadow: var(--gf-focus-ring-on-brand); }

/* Estado dispensado: some sem deixar espaço reservado. */
.gfm-demobar[hidden] { display: none; }
/* Estado carregando (app decidindo se está em modo demo): reserva a faixa. */
.gfm-demobar[data-state="loading"] .gfm-demobar__text,
.gfm-demobar[data-state="loading"] .gfm-demobar__actions { visibility: hidden; }


/* =============================================================================
   9. CABEÇALHO DO SITE — .gfm-siteheader · .gfm-skiplink
   -----------------------------------------------------------------------------
   Navegação pública da landing (logo + Recursos/Preços/Segurança + "Abrir o
   app"). Consumido SÓ pela landing estática — o app logado não tem cabeçalho de
   marketing, então não há wrapper React. Os .gfp-bar dos catálogos são chrome de
   preview, não este componente.

   Superfície de MARCA (navy): funde-se ao hero navy no topo e ganha contraste ao
   rolar sobre as faixas claras. Por ser superfície de marca, herda o anel de foco
   --gf-focus-ring-on-brand (o azul padrão sumiria). Sticky; a altura ~64px casa
   com o scroll-margin-block-start de 72px das seções.

   Sem JS: em telas estreitas a navegação inline colapsa (o rodapé carrega o mapa
   completo) e ficam o lockup + o CTA de ouro. Nada de menu-hambúrguer com estado,
   que exigiria script.
   ========================================================================== */

/* Salta a navegação e vai direto ao conteúdo. Fora da tela até receber foco. */
.gfm-skiplink {
  position: absolute;
  left: var(--sp-4);
  top: var(--sp-4);
  z-index: 60;
  transform: translateY(-160%);
  padding: var(--sp-4) var(--sp-6);
  background: var(--gf-surface);
  color: var(--gf-blue);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  text-decoration: none;
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-float);
  transition: transform var(--gf-dur) var(--gf-ease);
}
.gfm-skiplink:focus-visible {
  transform: translateY(0);
  outline: none;
  box-shadow: var(--gf-focus-ring), var(--shadow-float);
}

.gfm-siteheader {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--gf-brand-navy);
  color: var(--gf-on-brand);
}
.gfm-siteheader__inner {
  max-width: var(--gf-container);
  margin-inline: auto;
  padding: var(--sp-4) var(--gf-gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-6);
}

.gfm-siteheader__lockup {
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-2xl);
  font-weight: var(--fw-black);
  letter-spacing: -.02em;
  color: var(--gf-on-brand);
  text-decoration: none;
}
/* Espaço só entre ícone e wordmark. `gap` no container separaria também "Grana"
   de <em>Flow</em> (itens flex distintos) e quebraria a marca em "Grana Flow". */
.gfm-siteheader__lockup svg { width: 26px; height: 26px; flex: none; margin-inline-end: var(--sp-3); }
/* O "Flow" do lockup sobre navy — mesmo valor do rodapé e do template de e-mail. */
.gfm-siteheader__lockup em { font-style: normal; color: var(--gf-on-brand-accent); }
.gfm-siteheader__lockup:focus-visible { outline: none; box-shadow: var(--gf-focus-ring-on-brand); border-radius: var(--r-xs); }

/* Navegação inline: só do tablet pra cima. No mobile o rodapé é o mapa. */
.gfm-siteheader__nav { display: none; }
@media (min-width: 768px) {
  .gfm-siteheader__nav {
    display: flex;
    align-items: center;
    gap: var(--sp-7);
    margin-inline-start: auto;
  }
}
.gfm-siteheader__link {
  font-size: var(--fs-base);
  font-weight: var(--fw-semi);
  color: var(--gf-on-brand-muted);
  text-decoration: none;
  padding-block: var(--sp-2);
  border-radius: var(--r-xs);
}
@media (hover: hover) { .gfm-siteheader__link:hover { color: var(--gf-on-brand); } }
.gfm-siteheader__link:focus-visible { outline: none; box-shadow: var(--gf-focus-ring-on-brand); }
/* Página atual — marcada por aria-current="page", não por cor inventada. */
.gfm-siteheader__link[aria-current="page"] { color: var(--gf-on-brand); }

.gfm-siteheader__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  flex: none;
}
@media (min-width: 768px) { .gfm-siteheader__actions { margin-inline-start: 0; } }

/* =============================================================================
   Compare — "antes / depois" lado a lado
   -----------------------------------------------------------------------------
   Nasceu do #265: a landing precisa mostrar a troca (planilha → app) sem pedir
   que o visitante imagine. Dois lados, um contraste.

   ⛔ O contraste é NEUTRO → MARCA, nunca vermelho → verde. Verde e vermelho são
   exclusivos de receita e despesa (invariante do DS): pintar "a planilha" de
   vermelho gastaria a cor que só o dinheiro pode usar, e num app financeiro isso
   confunde de verdade. O lado "antes" é apagado (surface-soft + muted); o lado
   "depois" é a marca. A hierarquia vem de peso e cor de marca, não de semáforo.

   Estados: este é bloco de CONTEÚDO estático — não tem hover, foco, desabilitado,
   erro nem carregando. O estado "vazio" é não renderizar a seção (a landing é
   estática; um comparativo sem lados não existe).
   ========================================================================== */
.gfm-compare {
  display: grid;
  gap: var(--sp-6);
  grid-template-columns: 1fr; /* empilhado no telefone: ler um, depois o outro */
}
@media (min-width: 768px) {
  .gfm-compare { grid-template-columns: 1fr 1fr; gap: var(--sp-7); align-items: stretch; }
}

.gfm-compare__side {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding: var(--sp-7);
  border-radius: var(--r-lg);
  border: 1px solid var(--gf-line-soft);
  background: var(--gf-surface-soft);
}
.gfm-compare__side--after {
  border-color: transparent;
  background: var(--gf-brand-navy-grad);
  color: var(--gf-on-brand);
  box-shadow: var(--shadow-xl);
}

.gfm-compare__label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--gf-muted);
}
.gfm-compare__side--after .gfm-compare__label { color: var(--gf-on-brand-muted); }

.gfm-compare__title {
  font-size: var(--gf-fs-h2);
  font-weight: var(--fw-bold);
  line-height: 1.2;
  color: var(--gf-text);
  margin: 0;
}
.gfm-compare__side--after .gfm-compare__title { color: var(--gf-on-brand); }

.gfm-compare__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.gfm-compare__item {
  display: flex;
  gap: var(--sp-3);
  align-items: flex-start;
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--gf-muted);
}
.gfm-compare__side--after .gfm-compare__item { color: var(--gf-on-brand-muted); }

/* Marcador: "—" no antes, "✓" no depois. Símbolo, não cor — quem enxerga em
   escala de cinza (ou não distingue vermelho de verde) lê o mesmo contraste. */
.gfm-compare__item::before {
  content: "—";
  flex: none;
  font-weight: var(--fw-bold);
  color: var(--gf-muted);
}
.gfm-compare__side--after .gfm-compare__item::before {
  content: "✓";
  color: var(--gf-gold);
}


/* =============================================================================
   11. CONSENTIMENTO DE MEDIÇÃO — .gfm-consent
   -----------------------------------------------------------------------------
   Faixa de escolha para carregar (ou não) o pixel de medição de anúncios. Só
   existe na landing pública: a área logada não carrega terceiros, e por isso não
   há wrapper React.

   POR QUE NÃO REUSAR .gfm-demobar
   O demobar AVISA (role="status", uma via, dispensável a qualquer momento). Este
   componente PERGUNTA: a página fica num estado indeterminado até a pessoa
   responder, e a resposta é persistida. Anatomia diferente (duas ações
   equivalentes, título, foco recebido), invariante diferente — componente
   próprio, não modificador.

   ⚖️ INVARIANTE LEGAL, NÃO ESTÉTICA: recusar tem de custar o mesmo que aceitar.
   Os dois botões são .gfm-cta--sm, mesma altura, mesma área de toque, um clique
   cada, ambos visíveis sem rolar. "Recusar" nunca vira link de texto, nunca vai
   para dentro de um "Saiba mais", nunca ganha menos contraste. Aceitar usa ouro
   porque ouro é a cor de CTA do DS — não para desequilibrar a escolha. Quem
   mexer aqui está mexendo na base legal do tratamento, não no visual.

   Superfície de MARCA (navy) flutuando no rodapé da viewport. Rodapé e não topo:
   o topo é do .gfm-siteheader sticky, e empurrar o hero para baixo na primeira
   visita gastaria justamente a dobra que a landing precisa.

   DUAS VARIANTES, dois momentos:
     · padrão (fixa)  → PERGUNTA, na primeira visita
     · --inline       → REVÊ, na página da Política. É o mecanismo de revogação,
       e a segunda existe por obrigação legal, não por simetria de design.

   Estados
     · repouso / hover / foco por teclado / ativo → herdados de .gfm-cta
     · DESABILITADO e ERRO → não existem, e isto é afirmação, não esquecimento.
       Decidir é síncrono: grava no localStorage e insere um <script>. Não há
       janela para desabilitar nem chamada de rede que possa falhar. Um estado
       "gravando" aqui seria decorativo — um spinner que nunca chega a pintar.
     · CARREGANDO → deliberadamente NÃO existe faixa. Antes de o script ler a
       escolha salva, nada é renderizado (o elemento nasce [hidden] no HTML).
       Reservar altura aqui seria pior que o pulo: mostraria esqueleto de uma
       pergunta que talvez já tenha sido respondida meses atrás.
     · VAZIO → escolha já registrada: o elemento permanece [hidden] e não ocupa
       espaço. É o estado da esmagadora maioria das visitas.
   ========================================================================== */

.gfm-consent {
  position: fixed;
  z-index: 50; /* acima do siteheader (40) e do demobar (30); abaixo do skiplink (60) */
  inset-inline: var(--sp-4);
  inset-block-end: var(--sp-4);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-4) var(--sp-6);
  max-width: 720px;
  margin-inline: auto;
  padding: var(--sp-6) var(--sp-7);
  border-radius: var(--r-md);
  /* A hairline NÃO é enfeite. O fundo da faixa é --gf-brand-navy (#0A2A5E), que
     é exatamente a cor final do gradiente do .gfm-hero: sobre a home a faixa
     ficava sem nenhuma separação de fundo, sustentada só pela sombra — e no tema
     escuro a sombra é preta sobre navy, quase nada. A borda resolve nos dois
     fundos, o navy do hero e as faixas claras das outras páginas. */
  border: 1px solid var(--gf-on-brand-line);
  background: var(--gf-brand-navy);
  color: var(--gf-on-brand);
  box-shadow: var(--shadow-float);
  font-size: var(--fs-base);
}

/* ---- Variante de GESTÃO — .gfm-consent--inline -------------------------------
   A mesma anatomia, dentro do fluxo do texto, na página da Política de
   Privacidade. Não é conveniência: é o único lugar onde a escolha pode ser
   REVISTA, e a LGPD (art. 8º §5 e art. 18, IX) exige que revogar seja tão fácil
   quanto consentir. Sem isto, a única saída documentada seria "limpe os dados do
   site" — que, nesta origem, apaga junto a CryptoKey do E2E e o histórico
   financeiro local. Nunca substitua este bloco por essa instrução. */
.gfm-consent--inline {
  position: static;
  z-index: auto;
  inset: auto;
  max-width: none;
  margin-block: var(--sp-7);
  box-shadow: none;
  animation: none;
}

/* Estado atual da escolha, em TEXTO. A cor não carrega informação aqui — quem
   lê em escala de cinza recebe a mesma frase. */
.gfm-consent__state {
  margin: 0;
  color: var(--gf-on-brand-muted);
  line-height: 1.5;
}
.gfm-consent__state strong { color: var(--gf-on-brand); font-weight: var(--fw-bold); }

.gfm-consent__body { flex: 1; min-width: 24ch; }

.gfm-consent__title {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  line-height: 1.3;
}

.gfm-consent__text {
  margin: 0;
  color: var(--gf-on-brand-muted);
  line-height: 1.5;
}

/* Link para a política. Herda a cor de link sobre marca de .gfm-on-brand, mas
   sublinhado explícito: sobre navy, cor sozinha não é affordance suficiente. */
.gfm-consent__text a { text-decoration: underline; }
.gfm-consent__text a:focus-visible { outline: none; box-shadow: var(--gf-focus-ring-on-brand); border-radius: var(--r-xs); }

/* As duas ações. `flex: none` nos dois: nenhum dos botões encolhe antes do
   outro quando falta largura — a simetria é o ponto. */
.gfm-consent__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}
.gfm-consent__actions .gfm-cta { flex: none; }

/* Estados carregando e vazio são o MESMO estado visual: ausência. */
.gfm-consent[hidden] { display: none; }

/* Telefone: a faixa ocupa a largura toda e as ações descem para a própria
   linha, cada botão com metade do espaço — a simetria sobrevive ao empilhamento. */
@media (max-width: 560px) {
  .gfm-consent {
    inset-inline: 0;
    inset-block-end: 0;
    border-radius: var(--r-md) var(--r-md) 0 0;
    border-inline: none;
    border-block-end: none; /* encostada na borda da tela, só o topo separa */
  }
  .gfm-consent__actions { width: 100%; }
  .gfm-consent__actions .gfm-cta { flex: 1; }
}

/* Sem animação para quem pediu menos movimento. */
@media (prefers-reduced-motion: no-preference) {
  .gfm-consent { animation: gfm-consent-in 180ms ease-out both; }
}
@keyframes gfm-consent-in {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
