/* ============================================================
   MEDVANCE — FOLHA DE ESTILO DO SITE
   Consome exclusivamente design-system/tokens.css.
   Nenhuma cor, fonte, raio ou espaçamento escrito na mão.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--mv-bg);
  color: var(--mv-text-body);
  font-family: var(--mv-font-body);
  font-size: var(--mv-text-base);
  line-height: var(--mv-leading-body);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }

.wrap { max-width: var(--mv-container); margin-inline: auto; padding-inline: var(--mv-gutter); }
.wrap-narrow { max-width: var(--mv-container-narrow); margin-inline: auto; padding-inline: var(--mv-gutter); }

/* Conteúdo só para leitor de tela e para robô de IA entender contexto */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* Atalho de teclado para pular o menu. Fica fora da tela até alguém
   dar Tab nele. Sem esta regra a frase "Ir para o conteúdo" aparece
   escrita no canto de cima da página, que foi o que acontecia em
   /especialidades/: a classe existia no HTML e não no CSS. */
.skip-link {
  position: absolute; top: 0; left: -9999px; z-index: 999;
  background: var(--mv-agua-900); color: var(--mv-text-on-dark);
  font-size: var(--mv-text-sm); text-decoration: none;
  padding: 12px 20px; border-radius: 0 0 var(--mv-radius-md) 0;
}
.skip-link:focus { left: 0; }

/* ── Tipografia base ───────────────────────────────────── */
h1, h2, h3 {
  font-family: var(--mv-font-display);
  font-weight: var(--mv-weight-semibold);
  line-height: var(--mv-leading-tight);
  color: var(--mv-text);
  margin: 0 0 var(--mv-space-2);
}
h1 { font-size: var(--mv-text-display-1); }
h2 { font-size: var(--mv-text-display-2); }
h3 { font-size: var(--mv-text-display-3); }
h4 {
  font-family: var(--mv-font-body);
  font-size: var(--mv-text-title);
  font-weight: var(--mv-weight-medium);
  line-height: var(--mv-leading-snug);
  color: var(--mv-text);
  margin: 0 0 var(--mv-space-1);
}
p { margin: 0 0 var(--mv-space-2); }
.lead { font-size: var(--mv-text-title); color: var(--mv-text-body); }

.eyebrow {
  font-family: var(--mv-font-eyebrow);
  font-size: var(--mv-text-sm);
  font-weight: var(--mv-weight-semibold);
  letter-spacing: var(--mv-tracking-eyebrow);
  text-transform: uppercase;
  line-height: var(--mv-leading-tight);
  color: var(--mv-agua-700);
  margin: 0 0 var(--mv-space-1);
}
.eyebrow-light { color: var(--mv-agua-200); }

/* Termo popular ao lado do técnico: regra de comunicação da clínica */
.popular { display: block; font-size: var(--mv-text-sm); color: var(--mv-text-muted); font-weight: var(--mv-weight-regular); }

/* ── Seções ────────────────────────────────────────────── */
section { padding-block: var(--mv-space-7); }
.section-head { max-width: 62ch; margin-bottom: var(--mv-space-5); }
.section-head p { color: var(--mv-text-muted); }
.section-alt { background: var(--mv-bg-alt); }
.section-dark { background: var(--mv-surface-dark); color: var(--mv-agua-100); }
.section-dark h2, .section-dark h3, .section-dark h4 { color: var(--mv-text-on-dark); }
.section-dark p { color: var(--mv-agua-100); }

/* ── Grades ────────────────────────────────────────────── */
.grid { display: grid; gap: var(--mv-gap-grid); }
@media (min-width: 768px) {
  .grid-2 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1025px) {
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
  .grid-4 { grid-template-columns: repeat(4, 1fr); }
}

/* ══════════════════════════════════════════════════════════
   SLOT DE IMAGEM
   Como preencher:
   1) trocar o <span class="img-slot__hint"> por um <img> e somar a classe
      is-filled na figure. É o método que vale para o Google, porque
      background-image não é rastreado. É o que a home usa hoje.
   2) só para decoração, sem valor de busca:
      style="background-image:url('assets/img/NOME.webp')"
   Não use url() dentro de custom property: o navegador resolve o caminho
   relativo a este arquivo CSS, e não ao HTML, e a imagem quebra.
   Consulte IMAGENS.md para nome, medida e alt de cada slot.
   ══════════════════════════════════════════════════════════ */
.img-slot {
  position: relative;
  display: block;
  /* <figure> nasce com margin: 1em 40px por conta do navegador.
     Sem zerar, quem manda no recuo da foto é o user-agent, e o
     40px dele nunca fecha com o espaçamento do sistema. */
  margin: 0;
  aspect-ratio: var(--ratio, 4 / 3);
  background-color: var(--mv-agua-50);
  background-size: cover;
  background-position: var(--pos, center);
  overflow: hidden;
  border: 2px dashed var(--mv-agua-500);
}
.img-slot > img { width: 100%; height: 100%; object-fit: cover; }
.img-slot__hint {
  position: absolute; inset: 0;
  display: grid; place-content: center; gap: 4px;
  text-align: center; padding: var(--mv-space-2);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: var(--mv-text-xs);
  line-height: 1.4;
  color: var(--mv-agua-800);
}
.img-slot__hint b { font-size: var(--mv-text-sm); letter-spacing: .5px; }
/* Slot preenchido: some o aviso e a borda tracejada */
.img-slot[style*="background-image"] { border-style: solid; border-color: transparent; }
.img-slot[style*="background-image"] .img-slot__hint,
.img-slot.is-filled .img-slot__hint { display: none; }
.img-slot.is-filled { border-style: solid; border-color: transparent; }

/* Retrato ainda sem foto: silhueta em vez da moldura de rascunho.
   O slot tracejado com o nome do arquivo dentro serve enquanto o site
   está em construção; no ar, ele mostra código interno no lugar do
   rosto do profissional. A silhueta ocupa a mesma medida, mantém o
   alinhamento da grade e não finge ser uma foto. */
.img-slot.is-icone {
  border-style: solid;
  border-color: transparent;
  background-color: var(--mv-agua-50);
  display: grid;
  place-items: center;
}
.img-slot.is-icone > svg {
  width: 44%; height: auto;
  color: var(--mv-agua-500);
  opacity: .5;
}

/* A foto real preenche a moldura e herda o recorte diagonal do slot. */
.img-slot > img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: var(--pos, center);
  display: block; border-radius: inherit;
}

/* Variações de recorte, seguindo a assinatura diagonal do sistema */
.img-leaf    { border-radius: var(--mv-radius-leaf); }
.img-leaf-md { border-radius: var(--mv-radius-leaf-md); }
.img-leaf-lg { border-radius: var(--mv-radius-leaf-lg); }
.img-notch   { border-radius: var(--mv-radius-notch); }
.img-circle  { border-radius: var(--mv-radius-circle); }

/* ══════════════════════════════════════════════════════════
   SEÇÃO COM IMAGEM DE FUNDO (capa de seção)
   Mesma lógica do .img-slot, só que ocupando a largura toda.

   Vazia  → fundo teal + etiqueta com o nome e a medida do slot
   Cheia  → foto com camada teal por cima, texto sempre legível

   Preencher:
   <section class="section-cover"
            data-slot="cover-institucional"
            data-medida="1920 x 900px"
            style="background-image:url('assets/img/cover-institucional-medvance.webp')">

   A camada escura por cima não é enfeite: sem ela, foto clara
   apaga o texto branco e o contraste reprova no WCAG.
   ══════════════════════════════════════════════════════════ */
.section-cover {
  position: relative;
  overflow: hidden;
  background-color: var(--mv-agua-900);
  background-size: cover;
  background-position: var(--pos, center);
  color: var(--mv-text-on-dark);
}
.section-cover::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--mv-agua-900) 88%, transparent),
    color-mix(in srgb, var(--mv-agua-900) 72%, transparent)
  );
}
.section-cover > * { position: relative; z-index: 1; }
.section-cover h2,
.section-cover h3,
.section-cover h4 { color: var(--mv-text-on-dark); }
.section-cover p { color: var(--mv-agua-100); }
.section-cover .section-head p { color: var(--mv-agua-100); }
.section-cover .step { border-left-color: var(--mv-agua-500); }
.section-cover .step-num { color: var(--mv-sol-200); }

/* Etiqueta do slot vazio. Some sozinha quando a foto entra.
   Exige data-slot: sem essa condição a etiqueta também aparecia em
   seção que nunca teve slot nenhum, escrevendo "SLOT:  ·  " com os
   attr() vazios. Era o retângulo tracejado no canto do agendamento. */
.section-cover[data-slot]:not([style*="background-image"])::after,
.closing[data-slot]:not([style*="background-image"])::after {
  content: "SLOT: " attr(data-slot) "  ·  " attr(data-medida);
  position: absolute; top: 14px; right: 14px; z-index: 2;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: var(--mv-text-xs);
  color: var(--mv-agua-100);
  border: 2px dashed var(--mv-agua-500);
  border-radius: var(--mv-radius-leaf);
  padding: 6px 12px;
}

/* Leve profundidade no desktop. Desligado no celular, onde o
   background fixo trava a rolagem, e para quem pediu menos
   movimento no sistema. */
@media (min-width: 1025px) and (prefers-reduced-motion: no-preference) {
  .section-cover { background-attachment: fixed; }
}

/* ── Botões ────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--mv-font-body);
  font-size: var(--mv-text-lg);
  font-weight: var(--mv-weight-medium);
  line-height: var(--mv-leading-snug);
  padding: 15px 30px;
  border: var(--mv-border-width-strong) solid transparent;
  border-radius: var(--mv-radius-leaf);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--mv-duration-base) var(--mv-ease),
              transform var(--mv-duration-fast) var(--mv-ease);
}
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 3px solid var(--mv-focus-ring); outline-offset: 3px; }
.btn svg { flex: none; }

.btn-whats { background: var(--mv-whatsapp); color: var(--mv-neutral-0); }
.btn-whats:hover { background: var(--mv-whatsapp-hover); }
.btn-primary { background: var(--mv-action); color: var(--mv-action-text); }
.btn-primary:hover { background: var(--mv-action-hover); }
.btn-secondary { background: transparent; color: var(--mv-agua-800); border-color: var(--mv-agua-700); }
.btn-secondary:hover { background: var(--mv-agua-50); }
.btn-on-dark { background: transparent; color: var(--mv-neutral-0); border-color: var(--mv-agua-500); }
.btn-on-dark:hover { background: var(--mv-agua-800); }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--mv-space-2); }

/* ── Cabeçalho ─────────────────────────────────────────── */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--mv-neutral-0) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: var(--mv-border-width) solid var(--mv-border);
}
.header-inner { display: flex; align-items: center; gap: var(--mv-space-3); padding-block: var(--mv-space-2); }
/* flex-shrink desligado: quando o menu cresce e o cabeçalho fica
   sem espaço, quem cede é o menu. O logo espremido por falta de
   largura é a única forma de ele sair distorcido, e essa linha
   fecha essa porta. */
.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; margin-right: auto; flex: 0 0 auto; }
/* O logo desenhado em CSS (.brand-mark + .brand-name + .brand-sub)
   era provisório, feito enquanto o arquivo oficial não existia.
   Saiu em 07/08/2026, quando o cliente mandou o PNG. */

/* ── Logo ──────────────────────────────────────────────────
   O arquivo é o logo oficial em PNG, exportado em 3x e
   convertido para WebP sem perda. Altura fixa e largura
   automática: o logo nunca distorce, seja qual for a tela.

   Duas versões, porque a palavra "Medvance" é verde-água e
   some no rodapé escuro. Na versão de fundo escuro a palavra
   é branca e o símbolo continua com as duas cores da marca.
   ────────────────────────────────────────────────────────── */
.brand-logo {
  display: block;
  height: 38px;
  width: auto;
  flex: 0 0 auto;
  /* trava de segurança: se algum dia uma largura for imposta de
     fora, a arte se encaixa dentro dela em vez de esticar. */
  object-fit: contain;
}
@media (min-width: 768px) { .brand-logo { height: 44px; } }

.site-footer .brand-logo { height: 42px; }

/* Marca d'água: o símbolo grande e discreto no canto de uma
   seção. É respiro visual, não decoração vazia. Fica atrás
   de tudo e some para quem pediu menos movimento na tela. */
.marca-dagua { position: relative; overflow: hidden; }
.marca-dagua::after {
  content: "";
  position: absolute;
  right: -70px; bottom: -90px;
  width: 320px; height: 320px;
  background: url("img/medvance-simbolo.webp") center / contain no-repeat;
  opacity: .07;
  pointer-events: none;
  z-index: 0;
}
.marca-dagua > * { position: relative; z-index: 1; }
@media (max-width: 767px) { .marca-dagua::after { width: 200px; height: 200px; right: -50px; bottom: -60px; } }

.site-nav { display: none; gap: var(--mv-space-3); }
/* nowrap: "A clínica" e "Corpo clínico" têm espaço no meio e o
   menu é flex. Sem isto o navegador quebra o item em duas linhas
   antes de considerar diminuir o vão entre eles. */
.site-nav a { color: var(--mv-text-body); text-decoration: none; font-size: var(--mv-text-sm); font-weight: var(--mv-weight-medium); padding-block: 6px; border-bottom: 2px solid transparent; white-space: nowrap; }
.site-nav a:hover { color: var(--mv-agua-800); border-bottom-color: var(--mv-agua-500); }

/* Onde a pessoa está agora. "page" é a página aberta, marcada no
   HTML de cada arquivo; "location" é a seção que está na tela na
   home, marcada pelo ui.js conforme a rolagem. O traço é coral
   porque o vão do menu já usa água no hover: duas cores diferentes
   evitam confundir "passei o mouse" com "estou aqui". */
.site-nav a[aria-current] {
  color: var(--mv-agua-900);
  font-weight: var(--mv-weight-bold);
  border-bottom-color: var(--mv-coral-500);
}
.site-nav a[aria-current]:hover { border-bottom-color: var(--mv-coral-600); }

/* Faixa rolável no celular. Antes de 1025px o menu simplesmente
   sumia e o header ficava só com a logo: quem entrava por um
   artigo do blog não tinha como chegar em mais nada sem voltar
   pela home.

   Hoje isto é o plano B: com JavaScript a faixa vira o menu que
   abre e recolhe, mais abaixo neste arquivo. O que sobra aqui é
   o que a pessoa vê se o ui.js não carregar, e por isso continua
   sendo um menu inteiro e não um botão morto. O degradê na
   direita é a pista de que a faixa continua para o lado. */
.site-nav {
  display: flex;
  gap: 18px;
  order: 3;
  width: 100%;
  margin-top: 6px;
  padding-bottom: 4px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  mask-image: linear-gradient(90deg, #000 88%, transparent 100%);
}
.site-nav::-webkit-scrollbar { display: none; }

/* row-gap zero porque o header quebra em duas linhas no celular
   e o gap de 30px do flex passa a valer entre a logo e o menu.
   Eram 30px de nada num cabeçalho grudado que já come 17% da
   tela em todas as rolagens da página. */
.header-inner { flex-wrap: wrap; row-gap: 0; }
.header-cta { display: none; }

@media (min-width: 1025px) {
  .site-nav {
    order: 0; width: auto; margin-top: 0; padding-bottom: 0;
    gap: 22px; overflow: visible; mask-image: none;
  }
  .header-inner { flex-wrap: nowrap; }
  .header-cta { display: inline-flex; font-size: var(--mv-text-sm); padding: 11px 22px; white-space: nowrap; }
}
@media (min-width: 1240px) { .site-nav { gap: var(--mv-space-3); } }

/* ── Menu que abre e recolhe, só no celular ────────────────
   A faixa que arrasta para o lado tinha um defeito de origem:
   ela mostra três dos sete itens e conta com a pessoa descobrir
   sozinha que o resto está fora do quadro. Quem não arrasta não
   sabe que existe "Corpo clínico" nem "Blog".

   O botão troca essa aposta por uma lista de sete linhas, todas
   visíveis de uma vez, e devolve ao cabeçalho fechado a altura
   que a faixa ocupava.

   Tudo aqui mora sob .js-on e abaixo de 1025px, que é onde o
   menu do desktop entra. Sem JavaScript o botão não existe e a
   faixa continua no lugar, porque um menu recolhido que ninguém
   consegue abrir é um site sem menu.
   ────────────────────────────────────────────────────────── */
.nav-toggle { display: none; }

@media (max-width: 1024px) {
  .js-on .nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px é o alvo que o dedo acerta sem mirar. Abaixo disso o
       toque erra e a pessoa acha que o site travou. */
    width: 44px;
    height: 44px;
    padding: 0;
    background: var(--mv-surface);
    border: var(--mv-border-width) solid var(--mv-border);
    border-radius: var(--mv-radius-sm);
    cursor: pointer;
    transition: background var(--mv-duration-base) var(--mv-ease),
                border-color var(--mv-duration-base) var(--mv-ease);
  }
  .js-on .nav-toggle:focus-visible { outline: 3px solid var(--mv-focus-ring); outline-offset: 3px; }
  .js-on .nav-toggle[aria-expanded="true"] {
    background: var(--mv-agua-50);
    border-color: var(--mv-agua-200);
  }

  /* Três traços que viram X. O do meio some, os de fora giram e
     se cruzam: é a mesma peça mudando de estado, e não um ícone
     trocando por outro, o que deixa claro que o botão desfaz o
     que acabou de fazer. */
  .nav-toggle-barras {
    position: relative;
    display: block;
    width: 20px;
    height: 2px;
    background: var(--mv-agua-900);
    border-radius: 2px;
    transition: background var(--mv-duration-fast) var(--mv-ease);
  }
  .nav-toggle-barras::before,
  .nav-toggle-barras::after {
    content: '';
    position: absolute;
    left: 0;
    width: 20px;
    height: 2px;
    background: var(--mv-agua-900);
    border-radius: 2px;
    transition: transform var(--mv-duration-base) var(--mv-ease);
  }
  .nav-toggle-barras::before { transform: translateY(-6px); }
  .nav-toggle-barras::after  { transform: translateY(6px); }

  .nav-toggle[aria-expanded="true"] .nav-toggle-barras { background: transparent; }
  .nav-toggle[aria-expanded="true"] .nav-toggle-barras::before { transform: rotate(45deg); }
  .nav-toggle[aria-expanded="true"] .nav-toggle-barras::after  { transform: rotate(-45deg); }
  /* Sem bloco de prefers-reduced-motion aqui: os tokens de duração
     já vão a zero sozinhos nesse modo, e as três transições acima
     leem deles. */

  /* A faixa vira lista. max-height e não display:none porque o
     conteúdo precisa continuar no HTML: são sete links internos
     por página, e link escondido de display não conta como link
     para quem rastreia o site. */
  .js-on .site-nav {
    flex-direction: column;
    gap: 0;
    width: 100%;
    order: 3;
    margin-top: 0;
    padding-bottom: 0;
    overflow: hidden;
    /* O degradê da faixa é horizontal. Numa lista vertical ele
       apagaria o fim de cada linha do menu. */
    mask-image: none;
    max-height: 0;
    transition: max-height var(--mv-duration-base) var(--mv-ease);
  }
  /* O respiro entra e sai junto com a lista. Em padding fixo ele
     sobraria como uma faixa vazia de 20px no cabeçalho fechado. */
  .js-on .site-nav.is-aberto { padding-block: 8px var(--mv-space-1); }

  .js-on .site-nav a {
    padding: 14px 12px;
    font-size: var(--mv-text-base);
    border-bottom: var(--mv-border-width) solid var(--mv-border);
    border-left: 3px solid transparent;
    border-radius: 0 var(--mv-radius-sm) var(--mv-radius-sm) 0;
  }
  .js-on .site-nav a:last-child { border-bottom: 0; }

  /* Na horizontal o item atual era um traço embaixo da palavra.
     Numa lista vertical, traço embaixo lê como separador: vira
     barra coral na lateral, que é onde o olho procura a marca de
     posição quando a leitura desce em vez de correr para o lado. */
  .js-on .site-nav a[aria-current] {
    border-bottom-color: var(--mv-border);
    border-left-color: var(--mv-coral-500);
    background: var(--mv-agua-50);
  }
}

/* ── Hero ──────────────────────────────────────────────────
   Foto da fachada sangrando pela direita, texto na esquerda
   sobre papel branco. Entre os dois não existe borda nem
   caixa: a própria foto vai se dissolvendo até virar o fundo
   da página.

   O desaparecimento é feito com máscara, não com uma camada
   branca por cima. A diferença importa: com máscara a foto
   some de verdade, com camada ela fica atrás de um véu e o
   branco do texto nunca fecha com o branco da página.

   No celular a conta não fecha, 42% de tela não cabe texto.
   Lá a foto desce para baixo do texto, de ponta a ponta, com
   o canto diagonal da marca.
   ────────────────────────────────────────────────────────── */
/* padding-block: 0 anula o respiro padrão de <section>. Quem
   controla o espaço aqui é o bloco de texto, porque a foto
   precisa encostar na borda de baixo, sem faixa branca. */
.hero { position: relative; overflow: hidden; background: var(--mv-bg); padding-block: 0; }

.hero-copy { padding-block: var(--mv-space-4) var(--mv-space-3); }
.hero-copy h1 { margin-bottom: var(--mv-space-3); }
.hero-copy .lead { margin-bottom: var(--mv-space-3); max-width: 46ch; }

/* O risco coral é a assinatura curta da marca no bloco. */
.hero-risco {
  display: block; width: 64px; height: 3px;
  background: var(--mv-coral-500);
  margin-bottom: var(--mv-space-2);
  transform-origin: left center;
}

.hero-nota {
  margin-top: var(--mv-space-3);
  font-size: var(--mv-text-sm);
  color: var(--mv-text-muted);
}

.hero-foto { position: relative; overflow: hidden; }
.hero-foto img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 45%;
  display: block;
}

/* Quem se posiciona agora é a coluna, não cada selo. Assim os dois
   sobem e descem juntos quando a foto muda de tamanho, e acrescentar
   um terceiro no futuro é uma linha de HTML e nenhuma de CSS. */
.hero-selos {
  position: absolute; left: var(--mv-space-3); bottom: var(--mv-space-3);
  z-index: 2;
  display: flex; flex-direction: column; gap: 8px;
  max-width: 250px;
}

.hero-selo {
  background: var(--mv-sol-200);
  color: var(--mv-neutral-900);
  padding: var(--mv-space-2) var(--mv-space-3);
  border-radius: var(--mv-radius-leaf);
  box-shadow: var(--mv-shadow-2);
  font-size: var(--mv-text-sm);
  line-height: var(--mv-leading-snug);
}
.hero-selo strong { display: block; font-size: var(--mv-text-title); font-family: var(--mv-font-display); }

/* O segundo selo é branco de propósito. Dois cartões amarelos um sobre
   o outro competem pelo olho e a pessoa não lê nenhum dos dois. O traço
   coral na lateral é o que impede que ele desapareça dentro da foto:
   sem isso, fundo claro sobre parede clara some.

   Ficava em 13px, o menor tamanho do sistema, e sumia. Sobe para 16px:
   a frase é a promessa mais concreta da página inteira e não pode ser a
   letra miúda. Ele não passa a competir com o cartão amarelo porque lá
   em cima o título sai em 22px de Cinzel, e a hierarquia se resolve no
   título, não no corpo. */
.hero-selo-nota {
  margin: 0;
  background: var(--mv-neutral-0);
  color: var(--mv-neutral-900);
  padding: 10px 14px;
  border-left: 3px solid var(--mv-coral-500);
  border-radius: 0 var(--mv-radius-sm) var(--mv-radius-sm) 0;
  box-shadow: var(--mv-shadow-1);
  font-size: var(--mv-text-sm);
  line-height: var(--mv-leading-snug);
}

/* Celular e tablet: foto empilhada abaixo do texto. */
@media (max-width: 1024px) {
  .hero::before {
    content: ""; position: absolute; top: -180px; right: -160px;
    width: 420px; height: 420px; border-radius: var(--mv-radius-circle);
    background: var(--mv-agua-50);
  }
  .hero-copy { position: relative; z-index: 1; }
  .hero-foto {
    aspect-ratio: 4 / 3;
    border-radius: var(--mv-radius-notch);
    margin-top: var(--mv-space-3);
  }
}

/* Em tela pequena o par come metade da foto. Encolhe. */
@media (max-width: 767px) {
  .hero-selos {
    left: var(--mv-space-2); bottom: var(--mv-space-2);
    max-width: 200px;
    gap: 6px;
  }
  .hero-selo {
    padding: 14px var(--mv-space-2);
    font-size: var(--mv-text-xs);
  }
  .hero-selo strong { font-size: var(--mv-text-lg); }
  /* No celular o corpo do cartão amarelo cai para 13px. Se a nota
     ficasse nos 16px do desktop ela passaria a ser o maior texto do
     par, e o olho leria a observação antes da promessa. Aqui os dois
     empatam em 13px e a ordem volta a ser de cima para baixo. */
  .hero-selo-nota { padding: 8px 12px; font-size: var(--mv-text-xs); }
}

/* Desktop: foto absoluta na direita, dissolvida pela máscara.
   O @supports não é preciosismo. Sem máscara a foto apareceria
   inteira debaixo do texto, e aí o layout empilhado é melhor
   do que um hero ilegível. */
@supports ((mask-image: linear-gradient(#000, #000)) or (-webkit-mask-image: linear-gradient(#000, #000))) {
  @media (min-width: 1025px) {
    .hero { display: flex; align-items: center; min-height: min(78vh, 660px); }
    .hero-copy { width: 100%; position: relative; z-index: 2; padding-block: var(--mv-space-5); }
    .hero-copy > * { max-width: 35rem; }
    /* Coluna estreita pede título menor. Em display-1 o H1 quebra
       em oito linhas e o hero vira uma parede de texto. */
    .hero-copy h1 { font-size: var(--mv-text-display-2); }
    .hero-foto {
      position: absolute; inset: 0 0 0 44%;
      z-index: 1; margin: 0; aspect-ratio: auto; border-radius: 0;
      /* A rampa começa em 14% e não em 0: o trecho da foto que
         fica atrás do fim das linhas de texto precisa estar
         zerado, não semitransparente. Texto sobre foto lavada
         reprova contraste do mesmo jeito. */
      -webkit-mask-image: linear-gradient(90deg, transparent 14%, #000 56%);
              mask-image: linear-gradient(90deg, transparent 14%, #000 56%);
    }
    /* 100px e não 50: o botão flutuante do WhatsApp é fixo a 16px da
       borda direita e tem 56px, então tudo que ficar a menos de 72px
       da borda nasce coberto por ele. Com um selo só a sobreposição
       pegava a moldura; com dois, pega o texto do segundo.

       O 80px embaixo é pela dobra: numa janela de 800px de altura o
       hero termina depois dela, e a 50px o segundo selo nascia
       cortado ao meio. É justamente ele que decide a viagem de quem
       mora a 40km, então não pode depender de rolagem. */
    .hero-selos { left: auto; right: var(--mv-space-7); bottom: var(--mv-space-6); }
  }
}

/* ── Entrada do hero ───────────────────────────────────────
   O hero já está na tela quando a página carrega, então ele
   não espera o observador de rolagem: anima sozinho, uma vez
   só, em cascata.

   Tudo aqui está preso ao .js-anim, que é a classe que o
   script põe no <html> depois de confirmar que a página
   consegue animar. É a mesma trava do resto do site, e existe
   por um motivo prático: uma animação que começa em opacity 0
   e nunca roda é conteúdo invisível, e conteúdo invisível o
   Google trata como texto escondido.
   ────────────────────────────────────────────────────────── */
@keyframes mv-sobe  { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes mv-foto  { from { opacity: 0; transform: scale(1.12); }      to { opacity: 1; transform: none; } }
@keyframes mv-risco { from { transform: scaleX(0); }                    to { transform: scaleX(1); } }

.js-anim .hero-copy > *              { animation: mv-sobe var(--mv-duration-slow) var(--mv-ease) both; }
.js-anim .hero-copy > *:nth-child(1) { animation-delay:  80ms; }
.js-anim .hero-copy > *:nth-child(2) { animation: mv-risco 700ms var(--mv-ease) both; animation-delay: 280ms; }
.js-anim .hero-copy > *:nth-child(3) { animation-delay: 180ms; }
.js-anim .hero-copy > *:nth-child(4) { animation-delay: 280ms; }
.js-anim .hero-copy > *:nth-child(5) { animation-delay: 380ms; }
.js-anim .hero-copy > *:nth-child(6) { animation-delay: 460ms; }
.js-anim .hero-foto img              { animation: mv-foto 1200ms var(--mv-ease) both; }
/* Os dois selos entram em fila, não juntos: assim o olho lê o de cima
   antes do de baixo aparecer, que é a ordem em que eles argumentam. */
.js-anim .hero-selo                  { animation: mv-sobe var(--mv-duration-slow) var(--mv-ease) both; animation-delay: 700ms; }
.js-anim .hero-selo-nota             { animation: mv-sobe var(--mv-duration-slow) var(--mv-ease) both; animation-delay: 840ms; }

@media (prefers-reduced-motion: reduce) {
  .js-anim .hero-copy > *,
  .js-anim .hero-foto img,
  .js-anim .hero-selo,
  .js-anim .hero-selo-nota { animation: none; }
}

/* Faixa de sinais de confiança */
.trust-bar { border-top: var(--mv-border-width) solid var(--mv-border); border-bottom: var(--mv-border-width) solid var(--mv-border); background: var(--mv-neutral-0); }
.trust-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--mv-space-3); padding-block: var(--mv-space-4); }
@media (min-width: 480px) { .trust-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 768px) { .trust-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* Ícone à esquerda, ocupando as duas linhas de texto. A fonte de
   display fica de fora aqui de propósito: Cinzel renderiza minúscula
   como versalete, e "15 especialidades" em versalete no tamanho de
   contador foi o que fazia a faixa parecer um painel de números com
   duas palavras soltas dentro. */
.trust-item {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  column-gap: var(--mv-space-2);
  row-gap: 2px;
}
.trust-item > svg {
  grid-row: 1 / span 2;
  width: 26px; height: 26px;
  color: var(--mv-agua-600);
  margin-top: 1px;
}
.trust-item strong {
  font-size: var(--mv-text-base);
  font-weight: var(--mv-weight-semibold);
  color: var(--mv-agua-800);
  line-height: 1.25;
}
.trust-item span { font-size: var(--mv-text-sm); color: var(--mv-text-muted); line-height: 1.4; }

/* ── Cartões ───────────────────────────────────────────── */
.card {
  background: var(--mv-surface);
  border: var(--mv-border-width) solid var(--mv-border);
  border-radius: var(--mv-radius-leaf-md);
  overflow: hidden;
  display: flex; flex-direction: column;
  transition: box-shadow var(--mv-duration-base) var(--mv-ease), transform var(--mv-duration-base) var(--mv-ease);
}
.card:hover { box-shadow: var(--mv-shadow-2); transform: translateY(-4px); }
/* A foto do card repete o corte diagonal da moldura que a segura,
   um degrau menor: 40px no cartão, 20px na foto. Mesmo desenho em
   escalas diferentes é o que faz a assinatura da marca ser lida
   como assinatura, e não como dois formatos brigando.

   O recuo é o mesmo padding do .card-body, então a borda esquerda
   da foto cai exatamente na primeira letra do título. */
.card .img-slot {
  border: 0;
  border-radius: var(--mv-radius-leaf);
  margin: var(--mv-space-3) var(--mv-space-3) 0;
}
.card-body { padding: var(--mv-space-3); flex: 1; display: flex; flex-direction: column; }
.card-body p { color: var(--mv-text-muted); font-size: var(--mv-text-sm); margin-bottom: var(--mv-space-2); }
.card-link {
  margin-top: auto; align-self: flex-start;
  font-size: var(--mv-text-sm); font-weight: var(--mv-weight-medium);
  color: var(--mv-agua-800); text-decoration: none;
  border-bottom: 2px solid var(--mv-agua-300); padding-bottom: 2px;
}
.card-link:hover { border-bottom-color: var(--mv-agua-700); }

/* Dois links no rodapé do mesmo cartão: a página da cidade e a rota no
   Maps. Soltos, os dois herdam margin-top:auto e o espaço livre acaba
   dividido entre eles, abrindo um vão no meio do cartão. */
.card-acoes {
  margin: var(--mv-space-1) 0 0; margin-top: auto;
  display: flex; flex-direction: column; gap: var(--mv-space-1); align-items: flex-start;
}
.card-acoes .card-link { margin-top: 0; }

/* ── Cartões de exame, versão apertada ─────────────────────
   Em quatro colunas o cartão tem uns 260px. O respiro de 30px
   que funciona num cartão largo come metade da largura aqui,
   então a foto e o corpo recuam para 20px. */
.exames-grid .card .img-slot {
  margin: var(--mv-space-2) var(--mv-space-2) 0;
}
.exames-grid .card-body { padding: var(--mv-space-2); }
.exames-grid .card-body .btn {
  margin-top: auto; width: 100%; justify-content: center;
  font-size: var(--mv-text-sm); padding: 11px 18px;
}
.exames-grid .card-more__in ul { font-size: var(--mv-text-sm); }
/* O termo popular colava no parágrafo e os dois viravam um bloco
   só de texto cinza. Um respiro separa o rótulo do conteúdo. */
.popular { margin-bottom: var(--mv-space-1); }

/* ── Bloco de chamada intermediário ────────────────────── */
/* O degradê corre na diagonal do canto reto para o canto cortado,
   e o coral entra só na ponta, como um respingo. O texto continua
   sobre o lado claro do gradiente, que é onde ele é legível. */
.callout {
  background:
    radial-gradient(120% 140% at 100% 100%,
      color-mix(in srgb, var(--mv-coral-200) 55%, transparent) 0%,
      transparent 55%),
    linear-gradient(118deg,
      var(--mv-agua-100) 0%,
      var(--mv-agua-200) 42%,
      var(--mv-agua-300) 100%);
  border-radius: var(--mv-radius-leaf-lg);
  padding: var(--mv-space-5) var(--mv-space-4);
  display: grid; gap: var(--mv-space-3);
}
@media (min-width: 1025px) { .callout { grid-template-columns: 1.4fr auto; align-items: center; padding-inline: var(--mv-space-6); } }
.callout h3, .callout p { color: var(--mv-text-on-agua); }
.callout p { margin: 0; }

/* ── Galeria por dentro da clínica ─────────────────────── */
.gallery { display: grid; gap: var(--mv-space-2); }
@media (min-width: 768px) {
  /* Dezesseis células, dezesseis ocupadas. A primeira peça vale
     quatro, as três largas valem duas cada e as seis quadradas
     fecham o resto: sem essa conta a última linha termina pela
     metade e o mosaico fica com um buraco no canto. */
  .gallery { grid-template-columns: repeat(4, 1fr); grid-auto-rows: 180px; }
  .gallery > *:nth-child(1) { grid-column: span 2; grid-row: span 2; }
  .gallery > *:nth-child(4),
  .gallery > *:nth-child(5),
  .gallery > *:nth-child(6) { grid-column: span 2; }
}
/* Mesmo corte diagonal do resto do site. A peça grande fica com
   o canto único de 80px, que é o gesto forte; as outras repetem
   em 20px, sem competir com ela. */
.gallery .img-slot { height: 100%; aspect-ratio: auto; min-height: 180px; border-radius: var(--mv-radius-leaf); }
.gallery .img-notch { border-radius: var(--mv-radius-notch); }

/* No celular o mosaico vira faixa que arrasta para o lado. Em
   coluna única as dez fotos empilhavam 3.377px, quatro telas e
   meia de foto seguida antes de chegar na próxima seção: quem
   rolava desistia no meio ou passava direto. Deitada, a mesma
   seção cabe em meia tela, e a foto cortada na direita é o que
   avisa que tem mais.

   Depois da regra de cima de propósito: as duas têm o mesmo peso
   de seletor, então quem vem por último é quem vale. */
@media (max-width: 767px) {
  .gallery {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .gallery::-webkit-scrollbar { display: none; }
  .gallery > * { flex: 0 0 80%; scroll-snap-align: center; }
  .gallery .img-slot { height: auto; min-height: 0; aspect-ratio: 4 / 3; }
}

/* ── Equipe ────────────────────────────────────────────── */
.doctor { text-align: center; }
.doctor .img-slot { aspect-ratio: 1; border-radius: var(--mv-radius-leaf); margin-bottom: var(--mv-space-2); }
.doctor h4 { margin-bottom: 2px; font-size: var(--mv-text-base); }
.doctor span { font-size: var(--mv-text-sm); color: var(--mv-text-muted); display: block; }
.doctor .reg { font-size: var(--mv-text-xs); color: var(--mv-agua-700); font-family: ui-monospace, Menlo, Consolas, monospace; }

/* ── Passos ────────────────────────────────────────────── */
.step { border-left: 3px solid var(--mv-agua-200); padding-left: var(--mv-space-3); }
.step-num {
  font-family: var(--mv-font-display); font-size: var(--mv-text-display-3);
  color: var(--mv-coral-500); line-height: 1; display: block; margin-bottom: 6px;
}

/* ── Cidades ───────────────────────────────────────────── */
.city-list { display: flex; flex-wrap: wrap; gap: var(--mv-space-2); list-style: none; padding: 0; margin: 0; }
.city-list li {
  background: var(--mv-neutral-0);
  border: var(--mv-border-width) solid var(--mv-agua-500);
  border-radius: var(--mv-radius-leaf);
  padding: 10px 20px;
  font-size: var(--mv-text-sm);
  color: var(--mv-text-body);
}
.city-list li strong { color: var(--mv-agua-900); }

/* ── Mapa do endereço ──────────────────────────────────── */
.mapa {
  margin-top: var(--mv-space-5);
  border: var(--mv-border-width) solid var(--mv-border);
  /* Canto arredondado simples, não o diagonal da marca: o mapa é
     conteúdo de terceiro, com cartão de endereço e botões colados
     nos cantos, e o recorte de 80px comia esses controles. */
  border-radius: var(--mv-radius-md);
  overflow: hidden;
  background: var(--mv-neutral-0);
}
.mapa iframe {
  display: block;
  width: 100%;
  height: 260px;
  border: 0;
}
@media (min-width: 768px) { .mapa iframe { height: 400px; } }
.mapa-nota {
  display: flex; flex-wrap: wrap; gap: var(--mv-space-1) var(--mv-space-3);
  align-items: baseline;
  margin: var(--mv-space-2) 0 0;
  font-size: var(--mv-text-sm);
  color: var(--mv-text-muted);
}
.mapa-nota a {
  font-weight: var(--mv-weight-medium);
  color: var(--mv-coral-900);
  text-decoration: none;
  border-bottom: 2px solid var(--mv-coral-200);
  padding-bottom: 2px;
}
.mapa-nota a:hover { border-bottom-color: var(--mv-coral-600); }

/* ── FAQ ───────────────────────────────────────────────── */
.faq-item {
  border-bottom: var(--mv-border-width) solid var(--mv-border);
  padding-block: var(--mv-space-2);
}
.faq-item h3 {
  font-family: var(--mv-font-body);
  font-size: var(--mv-text-title);
  font-weight: var(--mv-weight-medium);
  color: var(--mv-text);
  margin-bottom: var(--mv-space-1);
  line-height: var(--mv-leading-snug);
}
.faq-item p { margin-bottom: 0; color: var(--mv-text-body); }

/* ── Fechamento ────────────────────────────────────────── */
.closing {
  position: relative;
  background-color: var(--mv-surface-dark);
  background-size: cover; background-position: center;
  border-radius: var(--mv-radius-leaf-lg);
  overflow: hidden;
  color: var(--mv-text-on-dark);
  text-align: center;
  padding: var(--mv-space-6) var(--mv-space-3);
}
.closing::before {
  content: ""; position: absolute; inset: 0;
  background: color-mix(in srgb, var(--mv-agua-900) 82%, transparent);
}
.closing > * { position: relative; }
.closing h2 { color: var(--mv-text-on-dark); }
.closing p { color: var(--mv-agua-100); max-width: 56ch; margin-inline: auto; }

/* ── Rodapé ────────────────────────────────────────────── */
.site-footer { background: var(--mv-surface-dark); color: var(--mv-agua-100); padding-block: var(--mv-space-6) var(--mv-space-4); }
.site-footer a { color: var(--mv-agua-100); }
.footer-grid { display: grid; gap: var(--mv-space-4); }
/* quatro colunas so a partir de 900px: com o horario dentro,
   768px espremia a coluna do endereco a ponto de quebrar o CEP. */
/* No dedo, cada link do rodapé tinha 19px de altura com 15px de
   vão: alvo pequeno e vizinho perto, que é a receita do toque
   errado. A margem negativa devolve exatamente o que o padding
   tomou, então a área clicável cresce para 44px e o rodapé não
   fica um centímetro mais alto por causa disso. */
@media (hover: none) {
  .footer-grid li a,
  .footer-grid p > a { display: inline-block; padding-block: 9px; margin-block: -9px; }
}
@media (min-width: 560px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1.1fr; } }
.footer-grid h4 { color: var(--mv-text-on-dark); font-family: var(--mv-font-eyebrow); font-size: var(--mv-text-xs); text-transform: uppercase; letter-spacing: 2px; margin-bottom: var(--mv-space-2); }
.footer-list { list-style: none; padding: 0; margin: 0; font-size: var(--mv-text-sm); }
.footer-list li { margin-bottom: 8px; }
.footer-list a { text-decoration: none; }
.footer-list a:hover { text-decoration: underline; }
.legal {
  margin-top: var(--mv-space-5); padding-top: var(--mv-space-3);
  border-top: var(--mv-border-width) solid var(--mv-agua-800);
  font-size: var(--mv-text-xs); color: var(--mv-agua-200); line-height: 1.6;
}

/* ── Assinatura de quem fez o site ─────────────────────── */
/* Fica no rodapé de todas as páginas, abaixo do jurídico.
   É oferta, não crédito de bastidor: por isso tem chamada
   própria e não só o nome de quem assinou. O coral separa
   a linha do texto legal sem brigar com o teal da marca. */
.assinatura {
  margin-top: var(--mv-space-3); padding-top: var(--mv-space-2);
  border-top: var(--mv-border-width) solid var(--mv-agua-800);
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 10px var(--mv-space-2);
  font-size: var(--mv-text-xs); color: var(--mv-agua-200);
}
.assinatura strong { color: var(--mv-text-on-dark); font-weight: var(--mv-weight-semibold); }
/* .site-footer a pinta todo link do rodapé de água claro. Esta regra
   precisa do mesmo peso para vencer, senão o botão sai da cor errada. */
.site-footer .assinatura-cta {
  display: inline-flex; align-items: center; gap: 8px;
  border: var(--mv-border-width) solid var(--mv-coral-400);
  border-radius: var(--mv-radius-leaf);
  padding: 8px 18px;
  color: var(--mv-coral-300); text-decoration: none;
  font-weight: var(--mv-weight-semibold); white-space: nowrap;
  transition: background var(--mv-duration-base) var(--mv-ease),
              color var(--mv-duration-base) var(--mv-ease);
}
.site-footer .assinatura-cta:hover,
.site-footer .assinatura-cta:focus-visible {
  background: var(--mv-coral-400); color: var(--mv-agua-900); text-decoration: none;
}
.assinatura-cta::after { content: "\2192"; }

/* ── Botão flutuante de WhatsApp ───────────────────────── */
.whats-float {
  position: fixed; right: 16px; bottom: 16px; z-index: 60;
  width: 56px; height: 56px; border-radius: var(--mv-radius-circle);
  background: var(--mv-whatsapp); color: var(--mv-neutral-0);
  display: grid; place-items: center;
  box-shadow: var(--mv-shadow-2);
  text-decoration: none;
}
.whats-float:hover { background: var(--mv-whatsapp-hover); }
.whats-float:focus-visible { outline: 3px solid var(--mv-focus-ring); outline-offset: 3px; }

/* ── Animação de entrada ───────────────────────────────────
   O estado escondido só existe quando o script confirma que
   consegue animar (classe .js-anim no <html>). Sem JavaScript,
   com JavaScript quebrado ou em leitor que não roda script,
   o conteúdo aparece normalmente. Texto invisível por causa de
   animação é penalizado pelo Google e some para leitor de tela.
   ──────────────────────────────────────────────────────────── */
.js-anim .reveal { opacity: 0; transform: translateY(18px); }
.js-anim .reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity var(--mv-duration-slow) var(--mv-ease),
              transform var(--mv-duration-slow) var(--mv-ease);
}
@media (prefers-reduced-motion: reduce) {
  .js-anim .reveal { opacity: 1; transform: none; }
}

/* ══════════════════════════════════════════════════════════
   COMPONENTES INTERATIVOS
   Efeitos inspirados na biblioteca Aceternity, refeitos em CSS
   e JavaScript puros. A Aceternity é React com Tailwind e Framer
   Motion; este site é HTML estático, sem build. Trazer React aqui
   custaria o que o projeto tem de mais valioso, que é entregar
   HTML pronto para o Google e para as IAs lerem sem rodar nada.

   Duas travas governam tudo daqui para baixo:
   .js-on   → existe JavaScript, então bloco pode nascer fechado
   .js-anim → dá para animar, então bloco pode nascer invisível
   Sem as duas, todo o conteúdo aparece aberto e visível. Nenhum
   texto deste site depende de script para existir na página.
   ══════════════════════════════════════════════════════════ */

/* ── Luz que segue o cursor no cartão ──────────────────────
   O brilho fica na camada de baixo, atrás do conteúdo. A foto
   tem fundo próprio e cobre a luz; o corpo do cartão é
   transparente e deixa passar. Resultado: a luz acende no
   texto e não lava a imagem.
   ────────────────────────────────────────────────────────── */
.card { position: relative; }
.card > * { position: relative; z-index: 1; }
.card::after {
  content: "";
  position: absolute; inset: 0; z-index: 0;
  pointer-events: none; opacity: 0;
  background: radial-gradient(
    260px circle at var(--mv-x, 50%) var(--mv-y, 0%),
    color-mix(in srgb, var(--mv-agua-500) 38%, transparent),
    transparent 70%
  );
  transition: opacity var(--mv-duration-base) var(--mv-ease);
}
.card:hover::after,
.card:focus-within::after { opacity: 1; }
.card:hover { border-color: var(--mv-agua-500); }

/* ── Cartão que abre ───────────────────────────────────────
   O detalhe fica dentro do cartão e abre no lugar, sem tirar o
   leitor da página.

   Fecha com max-height e não com display:none. A diferença é a
   razão de ser deste bloco: display:none tira o texto do fluxo
   e enfraquece o sinal para busca, e a lista de sintomas aqui
   dentro é justamente o que faz o cartão ser encontrado por
   quem digita "dor no joelho" em vez de "ortopedista". Aberto
   ou fechado, ela continua no HTML, indexável e citável.

   A medida exata de cada cartão vem do JavaScript, porque só
   ele sabe a altura do conteúdo. Um max-height chutado no CSS
   faria a animação correr rápido demais nos cartões curtos.
   ────────────────────────────────────────────────────────── */
.card-more { overflow: hidden; }
.js-on .card-more {
  max-height: 0;
  opacity: 0;
  transition: max-height var(--mv-duration-slow) var(--mv-ease),
              opacity var(--mv-duration-base) var(--mv-ease);
}
.js-on .card.is-open .card-more { opacity: 1; }
.card-more__label {
  font-family: var(--mv-font-eyebrow);
  font-size: var(--mv-text-xs);
  font-weight: var(--mv-weight-semibold);
  letter-spacing: var(--mv-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--mv-agua-700);
  margin: 0 0 8px;
}
.card-more ul { margin: 0 0 var(--mv-space-2); padding-left: 18px; }
.card-more li {
  font-size: var(--mv-text-sm);
  line-height: var(--mv-leading-snug);
  color: var(--mv-text-body);
  margin-bottom: 6px;
}
.card-more li::marker { color: var(--mv-coral-500); }

/* Sem JavaScript o conteúdo já está aberto, e um botão que não
   fecha nada seria só um enfeite que confunde. */
.card-toggle { display: none; }
.js-on .card-toggle {
  display: inline-flex; align-items: center; gap: 9px;
  align-self: flex-start;
  background: transparent; border: 0; padding: 0;
  margin: 0 0 var(--mv-space-2);
  font-family: var(--mv-font-body);
  font-size: var(--mv-text-sm);
  font-weight: var(--mv-weight-medium);
  color: var(--mv-agua-800);
  cursor: pointer;
  transition: color var(--mv-duration-fast) var(--mv-ease);
}
/* Mesma conta do rodapé: 19px de botão vira 45px de área para o
   dedo, e a margem negativa segura o cartão na altura de antes. */
@media (hover: none) {
  .js-on .card-toggle { padding-block: 13px; margin-block: -13px var(--mv-space-2); }
}
.card-toggle::after {
  content: "";
  width: 7px; height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform var(--mv-duration-base) var(--mv-ease);
}
.card.is-open .card-toggle::after { transform: translateY(1px) rotate(-135deg); }
.card-toggle:hover { color: var(--mv-coral-900); }
.card-toggle:focus-visible { outline: 3px solid var(--mv-focus-ring); outline-offset: 4px; }

/* ── Filtro por área ───────────────────────────────────────
   Quinze cartões numa tela só é muito para escolher. O filtro
   corta a lista pela pergunta que a pessoa já tem na cabeça:
   é para mim, para meu filho, é dor, é da cabeça.

   Nasce em "todas". Nenhum cartão está escondido quando a
   página carrega, o que mantém as quinze especialidades
   visíveis para quem rastreia o site.
   ────────────────────────────────────────────────────────── */
.filtro { display: none; }
.js-on .filtro {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin-bottom: var(--mv-space-4);
}
.filtro-btn {
  font-family: var(--mv-font-body);
  font-size: var(--mv-text-sm);
  font-weight: var(--mv-weight-medium);
  line-height: 1;
  padding: 10px 18px;
  background: var(--mv-neutral-0);
  color: var(--mv-text-body);
  border: var(--mv-border-width) solid var(--mv-agua-500);
  border-radius: var(--mv-radius-leaf);
  cursor: pointer;
  transition: background var(--mv-duration-fast) var(--mv-ease),
              color var(--mv-duration-fast) var(--mv-ease),
              border-color var(--mv-duration-fast) var(--mv-ease);
}
.filtro-btn:hover { background: var(--mv-agua-50); }
.filtro-btn[aria-pressed="true"] {
  background: var(--mv-agua-800);
  border-color: var(--mv-agua-800);
  color: var(--mv-neutral-0);
}
.filtro-btn:focus-visible { outline: 3px solid var(--mv-focus-ring); outline-offset: 3px; }
/* Vale para o cartão e para o bloco inteiro de especialidade: em
   /especialidades/ o que o filtro esconde não é um card, é a seção
   com título, motivos e pergunta. */
.is-fora { display: none; }
.is-entra { animation: mv-sobe 420ms var(--mv-ease) both; }
@media (prefers-reduced-motion: reduce) { .is-entra { animation: none; } }

/* ── Legenda que sobe por baixo da foto ────────────────────
   Sempre pelo mesmo lado, em todas as fotos.

   Até agosto de 2026 ela entrava pela borda por onde o cursor
   tinha entrado, calculado no JavaScript. Na prática o mouse
   atravessa a galeria em diagonal e passa por várias fotos
   seguidas: a legenda saía por cima em uma, pela lateral na
   seguinte, e quem já estava com uma foto aberta via o texto
   escapar de lado enquanto o próximo entrava por outro canto.
   Movimento diferente a cada passada não lê como detalhe, lê
   como defeito. Um sentido só, e a galeria fica previsível.

   Em tela de toque não existe passar o mouse, então lá a
   legenda fica sempre visível. Escondê-la seria esconder o
   texto de metade das visitas.
   ────────────────────────────────────────────────────────── */
.gallery figcaption {
  position: absolute; inset: 0; z-index: 2;
  display: grid; align-content: end;
  padding: var(--mv-space-2);
  background: linear-gradient(
    0deg,
    color-mix(in srgb, var(--mv-agua-900) 90%, transparent) 0%,
    color-mix(in srgb, var(--mv-agua-900) 40%, transparent) 45%,
    transparent 75%
  );
  color: var(--mv-text-on-dark);
  font-size: var(--mv-text-sm);
  line-height: var(--mv-leading-snug);
  border-radius: inherit;
  opacity: 0;
  transform: translateY(100%);
  transition: opacity var(--mv-duration-base) var(--mv-ease),
              transform var(--mv-duration-base) var(--mv-ease);
}
.gallery .img-slot:hover figcaption,
.gallery .img-slot:focus-within figcaption { opacity: 1; transform: none; }
@media (hover: none) {
  .gallery figcaption { opacity: 1; transform: none; font-size: var(--mv-text-xs); }
}
@media (prefers-reduced-motion: reduce) {
  .gallery figcaption { transform: none; }
}

/* ── Trilho dos passos ─────────────────────────────────────
   No desktop os três passos deixam de ser três blocos soltos e
   viram uma linha do tempo: um trilho horizontal que se pinta
   de verde-água a coral quando a seção entra na tela, com o
   número dentro de um círculo apoiado nele.

   No celular o trilho não cabe, e lá continua valendo a barra
   vertical à esquerda de cada passo, que é o desenho original.
   ────────────────────────────────────────────────────────── */
.steps { position: relative; }
@media (min-width: 1025px) {
  /* z-index 0 e não "sem z-index": pseudo-elemento do pai é pintado
     depois dos filhos, então o trilho passava por cima do número e
     riscava o 01 no meio. */
  .steps::before,
  .steps::after {
    content: "";
    position: absolute; top: 22px; left: 23px; right: 23px; height: 2px;
    z-index: 0;
  }
  .steps::before { background: color-mix(in srgb, var(--mv-agua-200) 45%, transparent); }
  .steps::after {
    background: linear-gradient(90deg, var(--mv-agua-500), var(--mv-coral-500));
    transform: scaleX(0); transform-origin: left center;
    transition: transform 1400ms var(--mv-ease) 200ms;
  }
  .steps.is-in::after { transform: scaleX(1); }
  .steps .step {
    position: relative;
    border-left: 0;
    padding-left: 0;
    padding-top: 66px;
  }
  .steps .step-num {
    position: absolute; top: 0; left: 0; margin: 0; z-index: 1;
    width: 46px; height: 46px;
    display: grid; place-items: center;
    border-radius: var(--mv-radius-circle);
    background: var(--mv-agua-900);
    border: 2px solid var(--mv-agua-500);
    font-size: var(--mv-text-lg);
    line-height: 1;
  }
  .section-cover .steps .step-num { color: var(--mv-sol-200); }
}
@media (prefers-reduced-motion: reduce) {
  .steps::after { transition: none; transform: scaleX(1); }
}

/* ── Cabeçalho que encolhe ─────────────────────────────────
   Depois da primeira dobra o cabeçalho perde altura e ganha
   sombra. Devolve tela para o conteúdo sem tirar o botão de
   agendar do alcance.
   ────────────────────────────────────────────────────────── */
.site-header {
  transition: background var(--mv-duration-base) var(--mv-ease),
              box-shadow var(--mv-duration-base) var(--mv-ease);
}
.header-inner,
.site-header .brand-logo {
  transition: padding var(--mv-duration-base) var(--mv-ease),
              height var(--mv-duration-base) var(--mv-ease);
}
.site-header.is-stuck {
  background: color-mix(in srgb, var(--mv-neutral-0) 97%, transparent);
  box-shadow: var(--mv-shadow-2);
}
.site-header.is-stuck .header-inner { padding-block: 9px; }
.site-header.is-stuck .brand-logo { height: 32px; }
@media (min-width: 768px) { .site-header.is-stuck .brand-logo { height: 36px; } }

/* ── Médico ────────────────────────────────────────────────
   Base do cartão de profissional. A página de especialistas vai
   reusar isto: retrato, nome, CRM e RQE, e as etiquetas de
   especialidade. As etiquetas repetem o corte diagonal da marca
   em escala pequena, como as fotas dentro dos cartões.
   ────────────────────────────────────────────────────────── */
.doctor .img-slot { transition: transform var(--mv-duration-base) var(--mv-ease); }
.doctor:hover .img-slot { transform: translateY(-5px); }
.doctor-tags {
  display: flex; flex-wrap: wrap; gap: 6px;
  justify-content: center;
  margin-top: 10px;
}
.doctor-tag {
  font-size: var(--mv-text-xs);
  line-height: 1;
  padding: 5px 11px;
  background: var(--mv-agua-50);
  color: var(--mv-agua-900);
  border-radius: var(--mv-radius-leaf);
}

/* ── Carrossel do corpo clínico ────────────────────────────
   Cada cartão é um link inteiro para a página do profissional.
   Sem JavaScript a faixa é uma lista que rola com o dedo, o que
   já resolve no celular. Com JavaScript ela anda sozinha e para
   quando alguém encosta ou chega nela pelo teclado, que é a
   regra que separa carrossel de propaganda de rua.
   ────────────────────────────────────────────────────────── */
.carrossel {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  padding-block: 4px;
  /* sangra até a borda da tela: faixa cortada no meio da largura
     conta que tem mais coisa adiante melhor do que qualquer seta */
  margin-inline: calc(var(--mv-gutter) * -1);
  padding-inline: var(--mv-gutter);
  /* As duas pontas somem no fundo em vez de bater numa borda reta.
     É máscara, não degradê por cima: assim funciona sobre qualquer
     cor de seção e não precisa saber qual é o fundo. */
  -webkit-mask-image: linear-gradient(to right,
    transparent 0, #000 8%, #000 92%, transparent 100%);
          mask-image: linear-gradient(to right,
    transparent 0, #000 8%, #000 92%, transparent 100%);
}
.carrossel::-webkit-scrollbar { height: 6px; }
.carrossel::-webkit-scrollbar-thumb { background: var(--mv-agua-200); border-radius: 99px; }
/* O vão vai na margem do cartão, não em gap. Com gap, metade da
   fila mede quinze cartões e catorze vãos e meio, e a volta do
   laço dá um pulo de meio vão bem no meio da tela. */
.carrossel-trilho {
  display: flex;
  gap: 0;
  width: max-content;
}
.carrossel .doctor {
  flex: 0 0 210px;
  margin-right: var(--mv-space-3);
  scroll-snap-align: start;
  display: block;
  text-decoration: none;
  color: inherit;
  border-radius: var(--mv-radius-leaf-md);
  padding: 10px 10px var(--mv-space-2);
  transition: background var(--mv-duration-base) var(--mv-ease);
}
.carrossel .doctor:hover { background: var(--mv-agua-50); }
.carrossel .doctor:focus-visible { outline: 3px solid var(--mv-focus-ring); outline-offset: 3px; }
.carrossel .doctor h4 { color: var(--mv-text); }
.carrossel .doctor:hover h4 { color: var(--mv-agua-900); }
@media (min-width: 768px) { .carrossel .doctor { flex-basis: 240px; } }

/* Anda sozinho só depois que o JavaScript clona a fila. */
.js-anim .carrossel.is-rodando { overflow-x: hidden; }
.js-anim .carrossel.is-rodando .carrossel-trilho {
  animation: mv-desfila var(--mv-desfile, 60s) linear infinite;
}
.js-anim .carrossel.is-rodando:hover .carrossel-trilho,
.js-anim .carrossel.is-rodando:focus-within .carrossel-trilho { animation-play-state: paused; }
@keyframes mv-desfila {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* Quando a faixa não anda sozinha, a segunda volta de cartões
   deixa de servir para nada e vira repetição na mão de quem
   arrasta. Some com ela nos dois casos. */
@media (prefers-reduced-motion: reduce) {
  .js-anim .carrossel.is-rodando { overflow-x: auto; }
  .js-anim .carrossel.is-rodando .carrossel-trilho { animation: none; }
  .carrossel-trilho > [aria-hidden="true"] { display: none; }
}

/* Em tela de toque não existe hover, então a faixa nunca pararia
   para a pessoa tocar num médico: o desfile por transform fica de
   fora. Quem anda com a faixa aqui é o ui.js, empurrando o
   scrollLeft, e é ele quem para no toque e volta depois. */
@media (hover: none) {
  .js-anim .carrossel.is-rodando { overflow-x: auto; }
  .js-anim .carrossel.is-rodando .carrossel-trilho { animation: none; }
  /* A segunda volta de cartões só serve para fechar o laço sem
     emenda. Se o ui.js não assumiu a faixa, ela vira repetição na
     mão de quem arrasta: quinze médicos mostrados trinta vezes. */
  .carrossel:not(.toque-anda) .carrossel-trilho > [aria-hidden="true"] { display: none; }
}
/* Enquanto anda sozinha, o encaixe sai do caminho: ele puxaria a
   faixa de volta para o cartão mais próximo a cada quadro, e o
   passeio viraria um tranco. No arrasto do dedo ele volta, que é
   quando serve para alguma coisa. */
.carrossel.anda-sozinho { scroll-snap-type: none; }

/* Os dois carrosséis da home, especialidades e corpo clínico, fecham
   com o mesmo botão. A .carrossel-nota, que era um link sublinhado em
   coral, saiu junto com o último uso dela. */
.carrossel-acao { margin: var(--mv-space-3) 0 0; text-align: center; }

/* ── FAQ em acordeão ───────────────────────────────────────
   As oito perguntas estavam abertas e ocupavam uma tela inteira.
   Fechadas, a seção cabe de uma vez e a pessoa escolhe o que ler.
   A resposta continua no HTML mesmo fechada, porque é dela que
   sai a citação no ChatGPT e o trecho em destaque do Google.
   ────────────────────────────────────────────────────────── */
.faq-item h3 { margin-bottom: 0; }
.faq-btn {
  display: block; width: 100%;
  background: transparent; border: 0; padding: 0;
  font: inherit; color: inherit; text-align: left;
  cursor: default;
}
.js-on .faq-btn {
  cursor: pointer;
  padding-right: 40px;
  position: relative;
  transition: color var(--mv-duration-fast) var(--mv-ease);
}
.js-on .faq-btn::after {
  content: "";
  position: absolute; right: 8px; top: 50%;
  width: 9px; height: 9px;
  border-right: 2px solid var(--mv-coral-600);
  border-bottom: 2px solid var(--mv-coral-600);
  transform: translateY(-70%) rotate(45deg);
  transition: transform var(--mv-duration-base) var(--mv-ease);
}
.js-on .faq-item.is-open .faq-btn::after { transform: translateY(-20%) rotate(-135deg); }
.js-on .faq-btn:hover { color: var(--mv-coral-900); }
.js-on .faq-btn:focus-visible { outline: 3px solid var(--mv-focus-ring); outline-offset: 4px; }

.faq-resposta { overflow: hidden; }
.js-on .faq-resposta {
  max-height: 0;
  opacity: 0;
  transition: max-height var(--mv-duration-slow) var(--mv-ease),
              opacity var(--mv-duration-base) var(--mv-ease);
}
.js-on .faq-item.is-open .faq-resposta { opacity: 1; }
.faq-resposta p { padding-top: var(--mv-space-1); }

/* Marca coral na pergunta aberta: um traço curto na lateral, do
   lado de fora do texto, que diz onde a leitura está. */
.js-on .faq-item { position: relative; }
.js-on .faq-item::before {
  content: "";
  position: absolute; left: -14px; top: var(--mv-space-2); bottom: var(--mv-space-2);
  width: 3px; border-radius: 99px;
  background: var(--mv-coral-500);
  opacity: 0; transition: opacity var(--mv-duration-base) var(--mv-ease);
}
.js-on .faq-item.is-open::before { opacity: 1; }
@media (max-width: 767px) { .js-on .faq-item::before { left: -10px; } }

/* ── Coral nos títulos ─────────────────────────────────────
   O vermelho desbotado é a assinatura da marca e estava só no
   logo e em dois links. Aqui ele vira um traço curto embaixo do
   título de cada seção: aparece em toda página, sem gritar.
   ────────────────────────────────────────────────────────── */
.section-head h2 { position: relative; padding-bottom: 14px; }
.section-head h2::after {
  content: "";
  position: absolute; left: 0; bottom: 0;
  width: 54px; height: 3px; border-radius: 99px;
  background: var(--mv-coral-500);
}
.section-cover .section-head h2::after { background: var(--mv-coral-300); }
.section-head[style*="center"] h2::after,
[style*="text-align:center"] .section-head h2::after { left: 50%; transform: translateX(-50%); }

/* Grifo coral dentro de um título.
   Mesmo traço de 3px do ::after acima, mas envolvendo um trecho
   escolhido em vez do título inteiro. Serve para a virada da frase,
   o "Aqui não." depois de listar o problema.

   nowrap porque o traço é absoluto: se o trecho quebrasse em duas
   linhas, o sublinhado atravessaria as duas por fora. Só usar em
   trechos curtos, de duas ou três palavras.

   bottom em em, não em px, porque o mesmo grifo aparece em título
   com clamp: em px ele encostava no rabo do "q" de "Aqui" no
   tamanho grande e ficava longe demais no pequeno. */
.grifo { position: relative; white-space: nowrap; }
.grifo::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -0.12em;
  height: 3px; border-radius: 99px;
  background: var(--mv-coral-500);
}
.section-cover .grifo::after,
.closing .grifo::after { background: var(--mv-coral-300); }

/* O traço se desenha da esquerda para a direita quando a seção
   entra na tela, um tempo depois do texto para não competir com
   ele. Mesma proteção do .reveal: sem JS, nasce pronto. */
.js-anim .reveal .grifo::after { transform: scaleX(0); transform-origin: left center; }
.js-anim .reveal.is-in .grifo::after {
  transform: scaleX(1);
  transition: transform var(--mv-duration-slow) var(--mv-ease) 320ms;
}
@media (prefers-reduced-motion: reduce) {
  .js-anim .reveal .grifo::after { transform: none; }
}

/* Botão secundário ganha a borda coral no hover. Antes ele mudava
   só de tom de verde e o clique não parecia clique. */
.btn-secondary:hover { background: var(--mv-coral-50); border-color: var(--mv-coral-500); color: var(--mv-coral-900); }

/* ══════════════════════════════════════════════════════════════
   PÁGINA DE REGIÃO ATENDIDA
   Quem mora fora da cidade pergunta duas coisas antes de tudo:
   quanto tempo de estrada e por onde se vai. Por isso distância
   e rota vêm em cima, antes do texto, e não escondidas nele.
   ══════════════════════════════════════════════════════════════ */
.breadcrumb { margin-bottom: var(--mv-space-2); }
.breadcrumb ol {
  list-style: none; display: flex; flex-wrap: wrap; gap: 8px;
  padding: 0; margin: 0;
  font-size: var(--mv-text-sm); color: var(--mv-text-muted);
}
.breadcrumb li + li::before { content: "\203A"; margin-right: 8px; color: var(--mv-agua-500); }
.breadcrumb a { color: var(--mv-agua-800); text-decoration: none; border-bottom: 1px solid var(--mv-agua-200); }
.breadcrumb a:hover { border-bottom-color: var(--mv-coral-500); }

/* Etiquetas de distância e tempo dentro do cartão de cidade. */
.rota { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 var(--mv-space-2); }
.rota span {
  display: inline-block;
  background: var(--mv-agua-50);
  border: var(--mv-border-width) solid var(--mv-agua-100);
  border-radius: var(--mv-radius-pill);
  padding: 4px 12px;
  font-size: var(--mv-text-xs);
  font-weight: var(--mv-weight-medium);
  color: var(--mv-agua-900);
}
.rota .rota-km { background: var(--mv-coral-50); border-color: var(--mv-coral-100); color: var(--mv-coral-900); }

/* A cidade onde a clínica fica não concorre com as outras:
   ela é a origem, e a borda mais forte diz isso sem legenda. */
.cidade-sede { border-color: var(--mv-agua-500); }
.cidade h3 { margin-bottom: var(--mv-space-1); }

.nota-fonte {
  font-size: var(--mv-text-sm);
  color: var(--mv-text-muted);
  margin-top: var(--mv-space-3);
}

/* ══════════════════════════════════════════════════════════════
   ESPECIALIDADES EM FAIXA
   Na home as quinze áreas viraram faixa: quinze cartões em grade
   ocupavam cinco rolagens antes de a pessoa chegar nos exames.
   Em faixa a seção cabe numa tela e continua dizendo "são quinze",
   porque a fila cortada na borda conta que tem mais adiante.
   O conteúdo inteiro de cada área mora em /especialidades/.
   ══════════════════════════════════════════════════════════════ */
.carrossel .esp-card {
  flex: 0 0 200px;
  margin-right: var(--mv-space-3);
  scroll-snap-align: start;
  display: block;
  text-decoration: none;
  color: inherit;
  background: var(--mv-surface);
  border: var(--mv-border-width) solid var(--mv-border);
  border-radius: var(--mv-radius-leaf-md);
  padding: 10px 10px var(--mv-space-2);
  transition: background var(--mv-duration-base) var(--mv-ease),
              border-color var(--mv-duration-base) var(--mv-ease);
}
.carrossel .esp-card .img-slot {
  aspect-ratio: 4/3;
  border-radius: var(--mv-radius-leaf);
  margin-bottom: 12px;
}
/* Nome em span, não em h3: o carrossel é clonado para o laço
   ficar contínuo, e clonar título seria entregar trinta cabeçalhos
   ao robô para quinze especialidades. O h1 e os h2 de verdade
   moram em /especialidades/. */
.carrossel .esp-card .esp-nome {
  display: block;
  font-family: var(--mv-font-body);
  font-size: var(--mv-text-base);
  font-weight: 600;
  line-height: 1.25;
  margin: 0 0 2px;
  color: var(--mv-text);
}
.carrossel .esp-card .popular { font-size: var(--mv-text-xs); }
.carrossel .esp-card:hover { background: var(--mv-agua-50); border-color: var(--mv-agua-200); }
.carrossel .esp-card:hover .esp-nome { color: var(--mv-agua-900); }
.carrossel .esp-card:focus-visible { outline: 3px solid var(--mv-focus-ring); outline-offset: 3px; }
@media (min-width: 768px) { .carrossel .esp-card { flex-basis: 230px; } }

/* ══════════════════════════════════════════════════════════════
   PÁGINA DE ESPECIALIDADES
   Quinze blocos largos, um embaixo do outro, davam oito mil pixels
   de rolagem para uma decisão curta: qual delas é a minha. Agora
   cada área é um cartão numa grade de três colunas. A pergunta de
   cada especialidade saiu do cartão porque ela já está inteira no
   acordeão de dúvidas mais abaixo, e escrever a mesma resposta
   duas vezes na mesma página não ajuda quem lê nem quem indexa.
   ══════════════════════════════════════════════════════════════ */
.esp-grade { display: grid; gap: var(--mv-space-3); }
@media (min-width: 660px)  { .esp-grade { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .esp-grade { grid-template-columns: repeat(3, 1fr); } }

.esp-bloco {
  display: flex; flex-direction: column;
  background: var(--mv-surface);
  border: var(--mv-border-width) solid var(--mv-border);
  border-radius: var(--mv-radius-leaf-md);
  overflow: hidden;
  scroll-margin-top: 110px;
  transition: border-color var(--mv-duration-base) var(--mv-ease),
              transform var(--mv-duration-base) var(--mv-ease);
}
.esp-bloco:hover { border-color: var(--mv-agua-200); transform: translateY(-4px); }
/* A foto encosta na borda do cartão: quem arredonda aqui é o
   cartão, com overflow escondendo o canto da imagem. */
.esp-bloco .img-slot { border: 0; border-radius: 0; }

.esp-corpo {
  display: flex; flex-direction: column; flex: 1;
  padding: var(--mv-space-2) var(--mv-space-2) var(--mv-space-2);
}
.esp-bloco h2 { font-size: var(--mv-text-lg); margin-bottom: 2px; }
.esp-bloco .popular { margin-bottom: var(--mv-space-1); }
.esp-bloco p { font-size: var(--mv-text-sm); margin-bottom: var(--mv-space-1); }
/* A linha de quem vem de fora é informação de apoio, não a frase
   principal do cartão: fica menor e em cinza. */
.esp-bloco .esp-regional { color: var(--mv-text-muted); font-size: var(--mv-text-xs); }

.esp-quando { margin-top: var(--mv-space-1); }
.esp-quando h3 {
  font-family: var(--mv-font-body);
  font-size: var(--mv-text-xs);
  font-weight: var(--mv-weight-semibold);
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--mv-text-muted);
  margin-bottom: 6px;
}
/* Linha mais junta que a do texto corrido: são frases de duas ou
   três palavras, e a entrelinha de leitura longa fazia cada lista
   de cinco motivos ocupar mais que a própria foto do cartão. */
.esp-quando ul { margin: 0; padding-left: 1.05em; }
.esp-quando li { font-size: var(--mv-text-sm); line-height: 1.35; margin-bottom: 5px; }

/* O botão desce para o rodapé do cartão com margin-top:auto, para
   os quinze cartões terminarem na mesma linha mesmo com textos de
   tamanhos diferentes. */
.esp-acoes {
  margin: var(--mv-space-2) 0 0; padding-top: var(--mv-space-1);
  display: flex; flex-direction: column; gap: var(--mv-space-1);
}
.esp-bloco .esp-acoes { margin-top: auto; }
.esp-acoes .btn { width: 100%; justify-content: center; font-size: var(--mv-text-sm); padding: 11px 18px; }

/* O título do cartão leva para a página da especialidade. É link de
   texto, não botão: o azul de link dentro de um h2 serifado brigaria
   com a hierarquia, então herda a cor e só sublinha no hover. */
.esp-bloco h2 a { color: inherit; text-decoration: none; }
.esp-bloco h2 a:hover { text-decoration: underline; text-decoration-color: var(--mv-coral-600); text-underline-offset: 3px; }

/* ── Abertura de página interna ────────────────────────────
   Texto de um lado, foto do outro. Antes o texto parava no meio
   da largura e a outra metade ficava em branco. */
.pagina-topo { display: grid; gap: var(--mv-space-3); align-items: center; }
@media (min-width: 940px) {
  .pagina-topo { grid-template-columns: 1.1fr 0.9fr; gap: var(--mv-space-4); }
}
.pagina-topo .section-head { margin-bottom: 0; }
.pagina-topo .img-slot { border-radius: var(--mv-radius-leaf-lg); }
/* Os quinze sinônimos que a pessoa digita no Google (ginecologista,
   urologista, pediatra) precisam estar na página, mas não são a
   frase que abre a leitura: entram menores, abaixo do resumo. */
.esp-sinonimos { font-size: var(--mv-text-sm); color: var(--mv-text-muted); }

/* ── FAQ em duas colunas ───────────────────────────────────
   Vinte e uma perguntas numa coluna só viravam uma tela inteira de
   rolagem mesmo fechadas. Em cartão e em duas colunas a seção cabe
   quase de uma vez, e cada pergunta fica com cara de coisa que se
   clica. A resposta continua no HTML fechada, que é de onde sai a
   citação do ChatGPT e o trecho em destaque do Google. */
.faq-grade { display: grid; gap: var(--mv-space-2); align-items: start; }
@media (min-width: 820px) { .faq-grade { grid-template-columns: 1fr 1fr; } }
.faq-grade .faq-item {
  background: var(--mv-surface);
  border: var(--mv-border-width) solid var(--mv-border);
  border-radius: var(--mv-radius-leaf);
  padding: var(--mv-space-2);
  transition: border-color var(--mv-duration-base) var(--mv-ease);
}
.faq-grade .faq-item:hover { border-color: var(--mv-agua-200); }
.js-on .faq-grade .faq-item.is-open { border-color: var(--mv-coral-300); }
.faq-grade .faq-btn { font-size: var(--mv-text-sm); font-weight: var(--mv-weight-semibold); }
.faq-grade .faq-resposta p { font-size: var(--mv-text-sm); margin-bottom: 0; }
/* Dentro do cartão o traço coral da lateral não cabe: ele ficava
   pendurado do lado de fora da borda. Quem marca a pergunta aberta
   aqui é a própria borda do cartão. */
.js-on .faq-grade .faq-item::before { display: none; }

/* ============================================================
   HORÁRIO DE ATENDIMENTO
   Aparece no rodapé de todas as páginas e dentro da seção de
   agendamento da home. O estado "aberto agora" é escrito pelo
   ui.js; sem JavaScript o bloco continua legível, só não mostra
   o momento.
   ============================================================ */
.footer-horario { list-style: none; padding: 0; margin: 0; font-size: var(--mv-text-sm); }
.footer-horario li {
  display: flex; justify-content: space-between; gap: var(--mv-space-2);
  padding: 5px 0; border-bottom: 1px solid var(--mv-agua-800);
}
.footer-horario li:last-child { border-bottom: 0; }
.footer-horario time { font-weight: var(--mv-weight-semibold); color: var(--mv-text-on-dark); }
.footer-horario .fechado { color: var(--mv-agua-300); }

.agora {
  display: inline-block; margin-top: var(--mv-space-2);
  font-size: var(--mv-text-xs); font-weight: var(--mv-weight-semibold);
  letter-spacing: .4px; padding: 5px 12px; border-radius: var(--mv-radius-pill);
}
.agora::before {
  content: ''; display: inline-block; width: 7px; height: 7px;
  border-radius: 50%; margin-right: 7px; vertical-align: 1px; background: currentColor;
}
.agora.esta-aberto  { background: rgba(37, 211, 102, .16); color: #67e79b; }
.agora.esta-fechado { background: rgba(251, 119, 106, .16); color: var(--mv-coral-300); }

/* mesma informação em fundo claro, dentro da página */
.horario-card {
  background: var(--mv-surface); border: var(--mv-border-width) solid var(--mv-border);
  border-radius: var(--mv-radius-leaf); padding: var(--mv-space-4);
}
.horario-card h3 {
  font-family: var(--mv-font-eyebrow); font-size: var(--mv-text-xs);
  text-transform: uppercase; letter-spacing: var(--mv-tracking-eyebrow);
  color: var(--mv-agua-700); margin: 0 0 var(--mv-space-2);
}
.horario-card ul { list-style: none; padding: 0; margin: 0; font-size: var(--mv-text-sm); }
.horario-card li {
  display: flex; justify-content: space-between; gap: var(--mv-space-2);
  padding: 7px 0; border-bottom: 1px solid var(--mv-divider);
}
.horario-card li:last-child { border-bottom: 0; }
.horario-card time { font-weight: var(--mv-weight-semibold); color: var(--mv-text); }
.horario-card .fechado { color: var(--mv-text-muted); }
.horario-card .agora.esta-aberto  { background: rgba(23, 150, 90, .12);  color: #17965a; }
.horario-card .agora.esta-fechado { background: rgba(249, 82, 67, .12); color: var(--mv-coral-600); }

/* ============================================================
   CORPO CLÍNICO — página dedicada
   Índice em grade no topo, ficha longa por profissional abaixo.
   A ficha é <article> de propósito: cada uma é uma entidade
   Physician no schema, e o Google precisa achar o limite dela.
   ============================================================ */
.equipe-indice {
  display: grid; gap: var(--mv-space-3);
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  margin-top: var(--mv-space-4);
}
.equipe-indice a {
  display: block; text-decoration: none; color: inherit;
  overflow: hidden;
  background: var(--mv-surface); border: var(--mv-border-width) solid var(--mv-border);
  border-radius: var(--mv-radius-leaf); padding: 0;
  transition: border-color var(--mv-duration-base) var(--mv-ease),
              transform var(--mv-duration-base) var(--mv-ease),
              box-shadow var(--mv-duration-base) var(--mv-ease);
}
.equipe-indice a:hover {
  border-color: var(--mv-agua-500); transform: translateY(-3px);
  box-shadow: var(--mv-shadow-1);
}
/* Retrato 1x1 no topo do cartao. Quadrado porque e o mesmo recorte das
   fichas la embaixo: o rosto que a pessoa ve no indice e identico ao da
   ficha, sem susto de enquadramento no meio do caminho. */
.equipe-indice .img-slot {
  aspect-ratio: 1 / 1;
  border-radius: 0;
  border: 0;
  transition: transform var(--mv-duration-base) var(--mv-ease);
}
.equipe-indice a:hover .img-slot > img { transform: scale(1.04); }
.equipe-indice .img-slot > img { transition: transform var(--mv-duration-base) var(--mv-ease); }
.equipe-indice__txt { padding: var(--mv-space-3); }
.equipe-indice strong { display: block; font-size: var(--mv-text-base); line-height: var(--mv-leading-snug); }
.equipe-indice span { display: block; margin-top: 4px; font-size: var(--mv-text-sm); color: var(--mv-text-muted); }

/* Duas colunas no celular. O minmax de 210px cabe uma vez só numa
   tela de 375px, e o índice inteiro passava de 2.150px: duas telas
   e meia de atalho antes da primeira ficha. Índice que dá mais
   trabalho que a página não é atalho. */
@media (max-width: 767px) {
  .equipe-indice { grid-template-columns: 1fr 1fr; gap: var(--mv-space-1); }
  .equipe-indice a { padding: 0; }
  .equipe-indice__txt { padding: 12px 14px; }
  .equipe-indice strong { font-size: var(--mv-text-sm); }
  .equipe-indice span { font-size: var(--mv-text-xs); }
}

.ficha {
  display: grid; gap: var(--mv-space-4);
  padding: var(--mv-space-5) 0;
  border-top: var(--mv-border-width) solid var(--mv-divider);
  scroll-margin-top: 100px;
}
@media (min-width: 860px) { .ficha { grid-template-columns: 300px 1fr; align-items: start; } }

.ficha-foto { position: sticky; top: 100px; }
@media (max-width: 859px) { .ficha-foto { position: static; max-width: 300px; } }
.ficha-foto .img-slot { border-radius: var(--mv-radius-leaf-md); overflow: hidden; }

.ficha h2 { margin: 0; }
.ficha .esp,
.atende .esp { color: var(--mv-agua-700); font-weight: var(--mv-weight-semibold); margin: 6px 0 0; }
.ficha .reg,
.atende .reg {
  display: inline-block; margin-top: var(--mv-space-2);
  font-family: var(--mv-font-eyebrow); font-size: var(--mv-text-xs);
  letter-spacing: 1px; text-transform: uppercase;
  background: var(--mv-agua-50); color: var(--mv-agua-800);
  border-radius: var(--mv-radius-pill); padding: 5px 12px;
}
.ficha .popular,
.atende .popular { display: block; font-size: var(--mv-text-sm); color: var(--mv-text-muted); margin-top: 4px; }

/* ── Quem atende (páginas de especialidade) ────────────────────
   As quinze páginas de especialidade não diziam quem atende. Para
   conteúdo de saúde isso é o buraco mais caro que existe: o Google
   e as IAs leem página médica sem profissional identificado como
   texto sem responsável, e o paciente que vem de Tapiraí quer saber
   com quem vai falar antes de pegar a estrada.

   O CRM fica em pílula, no mesmo desenho da ficha do corpo clínico,
   para ser a primeira coisa que o olho pega depois do nome. É
   exigência da Resolução CFM 2.336/2023, não enfeite.

   Card menor que a .ficha: aqui é uma pessoa só, e a ficha completa
   vive em /corpo-clinico/. Este bloco apresenta e encaminha.
   ────────────────────────────────────────────────────────────── */
.atende {
  display: grid; gap: var(--mv-space-3);
  align-items: start;
  background: var(--mv-surface);
  border: var(--mv-border-width) solid var(--mv-divider);
  border-radius: var(--mv-radius-leaf-md);
  padding: var(--mv-space-4);
}
@media (min-width: 720px) { .atende { grid-template-columns: 180px 1fr; gap: var(--mv-space-4); } }
.atende .img-slot {
  aspect-ratio: 1; max-width: 220px;
  border-radius: var(--mv-radius-leaf); overflow: hidden; margin: 0;
}
.atende h3 { margin: 0; font-size: var(--mv-text-title); }
.atende p { margin-bottom: 0; }
.atende .atende-bio { margin-top: var(--mv-space-2); }
/* .esp-acoes nasceu para o card estreito da vitrine, onde botão
   empilhado e largura total é o certo. Aqui a coluna tem 800px: dois
   botões esticados nessa largura viram duas faixas. No celular a
   regra original continua valendo, que é onde ela funciona. */
.atende .esp-acoes { margin-top: var(--mv-space-3); }
@media (min-width: 720px) {
  .atende .esp-acoes { flex-direction: row; flex-wrap: wrap; gap: var(--mv-space-2); }
  .atende .esp-acoes .btn { width: auto; }
}

/* Linha do responsável técnico. Discreta de propósito: é informação
   de conformidade, não argumento de venda. Mas fica no corpo da
   página, não só no rodapé, porque é lá embaixo que ninguém lê. */
.resp-tecnico {
  margin-top: var(--mv-space-3);
  font-size: var(--mv-text-sm); color: var(--mv-text-muted);
  border-left: 3px solid var(--mv-agua-300);
  padding-left: var(--mv-space-2);
}
.resp-tecnico strong { color: var(--mv-text); font-weight: var(--mv-weight-semibold); }

/* Ficha de E-E-A-T ainda em branco.
   Espaço reservado: a clínica vai coletar formação, RQE e tempo de
   atuação com cada profissional. Enquanto não chega, o bloco fica
   visível como lembrete no site local, e sai do ar antes de publicar
   (basta apagar o data-vazio no gen_corpo.py). É melhor um espaço
   marcado do que um texto genérico ocupando o lugar. */
.eeat-vazio {
  margin: var(--mv-space-3) 0;
  border: 2px dashed var(--mv-coral-300);
  border-radius: var(--mv-radius-leaf);
  background: var(--mv-coral-50);
  padding: var(--mv-space-3);
  font-size: var(--mv-text-sm); color: var(--mv-coral-800);
}
.eeat-vazio strong { display: block; margin-bottom: 6px; }
.eeat-vazio ul { margin: 0; padding-left: 1.1em; }

.eeat { margin: var(--mv-space-3) 0; }
.eeat dl { display: grid; gap: 8px; margin: 0; }
@media (min-width: 560px) { .eeat dl { grid-template-columns: max-content 1fr; column-gap: var(--mv-space-3); } }
.eeat dt {
  font-family: var(--mv-font-eyebrow); font-size: var(--mv-text-xs);
  text-transform: uppercase; letter-spacing: 1px; color: var(--mv-agua-700);
}
.eeat dd { margin: 0; font-size: var(--mv-text-sm); }

.ficha-faq { margin-top: var(--mv-space-4); }
.ficha-faq > h3 {
  font-family: var(--mv-font-eyebrow); font-size: var(--mv-text-xs);
  text-transform: uppercase; letter-spacing: var(--mv-tracking-eyebrow);
  color: var(--mv-agua-700); margin: 0 0 var(--mv-space-2);
}

/* ============================================================
   VISUALIZADOR DE IMAGEM
   O .img-slot recorta a foto no centro para a grade ficar
   alinhada. Aqui a foto aparece inteira, no maior tamanho que
   couber na tela, com seta para percorrer as fotos da mesma
   seção. Sem JavaScript nada disso existe, e a página segue
   igual: o cartão só é criado pelo ui.js.
   ============================================================ */
.js-on img.amplia { cursor: zoom-in; }
/* Dentro de link o clique continua sendo do link, então o cursor
   também: a lupa no canto é que abre a imagem. */
.js-on a img.amplia { cursor: inherit; }
.js-on img.amplia:focus-visible {
  outline: 3px solid var(--mv-focus-ring);
  outline-offset: 3px;
}

/* Lupa sobre a foto que já é link */
.lupa {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  width: 34px; height: 34px; display: grid; place-items: center;
  border: 0; border-radius: var(--mv-radius-circle); cursor: zoom-in;
  font-size: 17px; line-height: 1;
  color: var(--mv-neutral-0);
  background: color-mix(in srgb, var(--mv-agua-900) 55%, transparent);
  backdrop-filter: blur(2px);
  opacity: 0; transform: scale(.9);
  transition: opacity var(--mv-duration-fast) var(--mv-ease),
              transform var(--mv-duration-fast) var(--mv-ease),
              background var(--mv-duration-fast) var(--mv-ease);
}
.lupa:hover { background: var(--mv-agua-700); }
/* Aparece no hover do cartão, e sempre que receber foco pelo
   teclado: botão invisível que não dá para alcançar não é botão.
   Em tela de toque não existe hover, então fica sempre visível. */
.img-slot:hover .lupa,
.card:hover .lupa,
.lupa:focus-visible { opacity: 1; transform: none; }
.lupa:focus-visible { outline: 2px solid var(--mv-neutral-0); outline-offset: 2px; }
/* Em tela de toque a lupa cresce para 44px, que é o alvo mínimo
   que o dedo acerta sem errar. Com 34px ela ficava abaixo disso
   e ainda encostada no canto da foto, onde o polegar tende a
   pegar a borda em vez do botão. */
@media (hover: none) {
  .lupa { opacity: 1; transform: none; width: 44px; height: 44px; font-size: 19px; }
}

/* Trava a rolagem do fundo: rolar a página atrás do cartão
   aberto faz a pessoa perder o lugar onde estava. */
body.lente-aberta { overflow: hidden; }

.lente {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: var(--mv-space-3);
}
.lente[hidden] { display: none; }

.lente-fundo {
  position: absolute; inset: 0;
  background: color-mix(in srgb, var(--mv-agua-900) 88%, transparent);
  animation: lente-entra var(--mv-duration-fast) var(--mv-ease);
}

.lente-cartao {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: var(--mv-space-2);
  max-width: min(1100px, 100%);
}

.lente-cartao figure {
  margin: 0; background: var(--mv-neutral-0);
  border-radius: var(--mv-radius-leaf-md);
  padding: var(--mv-space-2);
  box-shadow: var(--mv-shadow-2);
  animation: lente-sobe var(--mv-duration-base) var(--mv-ease);
}
.lente-cartao img {
  display: block; max-width: 100%;
  /* desconta a barra da legenda e a folga do cartão */
  max-height: calc(100vh - 190px);
  width: auto; height: auto;
  border-radius: var(--mv-radius-sm);
  background: var(--mv-bg-alt);
}

.lente-cartao figcaption {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--mv-space-3);
  padding: var(--mv-space-2) 4px 2px;
  font-size: var(--mv-text-sm); color: var(--mv-text-muted);
}
/* A legenda é o alt da foto, que já descreve a cena para quem
   não enxerga. Aqui ela vira contexto para quem enxerga. */
.lente-texto { line-height: var(--mv-leading-snug); }
.lente-conta { flex: none; font-variant-numeric: tabular-nums; }

.lente-seta, .lente-x {
  flex: none; display: grid; place-items: center;
  border: 0; cursor: pointer; color: var(--mv-neutral-0);
  background: color-mix(in srgb, var(--mv-neutral-0) 16%, transparent);
  transition: background var(--mv-duration-fast) var(--mv-ease);
}
.lente-seta:hover, .lente-x:hover {
  background: color-mix(in srgb, var(--mv-neutral-0) 30%, transparent);
}
.lente-seta:focus-visible, .lente-x:focus-visible {
  outline: 2px solid var(--mv-neutral-0); outline-offset: 2px;
}
.lente-seta {
  width: 48px; height: 48px; border-radius: var(--mv-radius-circle);
  font-size: 30px; line-height: 1; padding-bottom: 4px;
}
.lente-seta[hidden] { display: none; }
.lente-x {
  position: absolute; top: -14px; right: -14px; z-index: 2;
  width: 38px; height: 38px; border-radius: var(--mv-radius-circle);
  font-size: 24px; line-height: 1;
  background: var(--mv-agua-700);
}

@keyframes lente-entra { from { opacity: 0; } }
@keyframes lente-sobe {
  from { opacity: 0; transform: translateY(14px) scale(.985); }
}
@media (prefers-reduced-motion: reduce) {
  .lente-fundo, .lente-cartao figure { animation: none; }
}

/* No celular a seta ao lado da foto rouba a largura que a foto
   precisa. Elas descem para baixo da legenda, lado a lado. */
@media (max-width: 700px) {
  .lente { padding: var(--mv-space-2); }
  .lente-cartao { flex-wrap: wrap; justify-content: center; }
  .lente-cartao figure { order: 1; width: 100%; }
  .lente-seta { order: 2; }
  .lente-cartao img { max-height: calc(100vh - 250px); }
  .lente-x { top: -10px; right: -6px; }
}

/* ── Dedo, não mouse ───────────────────────────────────────
   Medido a 375x812: pergunta de FAQ de uma linha 19px, de duas
   linhas 38px, filtro 38px, link de cartão 30px. Tudo abaixo dos
   44px que o dedo acerta sem erro. Por isso min-height, e não só
   padding: a pergunta curta precisava crescer 25px, a longa 6px.
   Sobe só onde o ponteiro é grosso, para o desktop continuar com
   o mesmo respiro de antes.
   ────────────────────────────────────────────────────────── */
@media (pointer: coarse) {
  .js-on .faq-btn { min-height: 44px; display: flex; align-items: center; padding-block: 5px; }
  .filtro-btn { min-height: 44px; }
  .card-link { padding-block: 9px 7px; }
  .brand { min-height: 44px; }
  .site-footer .assinatura-cta { min-height: 44px; }
  .breadcrumb a { display: inline-block; padding-block: 12px; }
  .card-acoes { gap: 0; }
  .mapa-nota a { display: inline-block; padding-block: 9px; }
}
