/* ============================================================
   NÚCLEO — Camada 1 do design system
   Feito UMA vez. Serve todos os nichos, para sempre.

   Não define cor nem fonte: isso é do kit de nicho (camada 2).
   Define RITMO — escala, espaço, contraste, comportamento.
   É ~80% do que faz uma página parecer profissional, e é invisível.
   ============================================================ */

:root {
  /* --- Escala tipográfica ---------------------------------
     Medida na Clínica Suganuma: display 82,8px contra corpo 17px = 4,9×.
     Contraste violento de tamanho é METADE da sensação de "isso foi
     desenhado". Página amadora usa 28px contra 16px e fica morna.      */
  --texto-micro: 0.75rem;   /* 12px — sobrelinha, legenda */
  --texto-peq:   0.875rem;  /* 14px */
  --texto-base:  1.0625rem; /* 17px — corpo */
  --texto-md:    1.25rem;   /* 20px — subtítulo de hero */
  --texto-lg:    1.75rem;   /* 28px */
  --texto-xl:    2.2rem;    /* 35px — display no celular */
  --texto-2xl:   3.5rem;    /* 56px — título de seção */
  --texto-3xl:   4rem;      /* 64px — display no desktop. 84px virava manifesto:
                               a headline tomava a tela e empurrava o CTA para fora */

  /* --- Entrelinha: a regra contraintuitiva ---------------
     Quanto MAIOR o texto, mais APERTADA a entrelinha. Título grande com
     entrelinha folgada esparrama e perde força; corpo apertado fica
     ilegível. Medido na referência: 1,04 no display, 1,6 no corpo.      */
  --altura-display: 1.04;
  --altura-titulo:  1.15;
  --altura-corpo:   1.6;

  /* Espaçamento entre letras: só existe em tamanho grande. */
  --letra-display: -0.022em;
  --letra-titulo:  -0.012em;
  --letra-micro:    0.14em;  /* sobrelinha em caixa alta */

  /* --- Espaçamento — escala de 4px ---------------------- */
  --e1: 0.25rem;  --e2: 0.5rem;   --e3: 0.75rem;  --e4: 1rem;
  --e6: 1.5rem;   --e8: 2rem;     --e12: 3rem;    --e16: 4rem;
  --e20: 5rem;    --e24: 6rem;    --e32: 8rem;

  /* --- Medidas ------------------------------------------ */
  --largura-texto: 38rem;   /* ~70 caracteres: o limite do conforto de leitura */
  --largura-pagina: 76rem;
  --respiro-lateral: 1.25rem;  /* nunca deixar o texto encostar na borda do celular */

  /* --- Forma --------------------------------------------
     Canto arredondado acima de 8px começa a parecer template de 2014.   */
  --raio-p: 3px;
  --raio-m: 6px;
  --raio-pilula: 999px;

  --transicao: 180ms cubic-bezier(0.4, 0, 0.2, 1);
}

@media (min-width: 48rem) {
  :root { --respiro-lateral: 2.5rem; }
}

/* ============================================================
   PROIBIÇÕES — as restrições negativas do sistema

   Silêncio no design system = a IA usa o padrão, e o padrão é a média
   da internet. Estas regras existem para tirar decisões da mesa:

   ✗ gradiente roxo-azul (ou qualquer gradiente como fundo de seção)
   ✗ fonte Inter, Roboto ou Open Sans — corretas e anônimas
   ✗ três cards com ícone genérico preenchendo espaço
   ✗ cinza neutro: todo tom cinza tem que puxar para o matiz do kit
   ✗ azul ou roxo em qualquer lugar, salvo se for cor real da marca
   ✗ border-radius acima de 8px
   ✗ sombra difusa grande (aquela "elevação" de material design)
   ✗ hero com menos de 85vh
   ✗ texto sobre foto sem camada de contraste
   ✗ título de seção como rótulo ("Serviços", "Sobre", "Contato")
     → tem que ser frase ("O que tratamos.", "Quem cuida de você.")
   ✗ DOIS botões no hero. Landing page tem UM objetivo; o segundo botão
     divide a atenção e rouba clique do principal. Padrão: WhatsApp.
     Telefone só quando o WhatsApp não estiver confirmado — botão que
     não abre nada quando o dono toca é pior que botão nenhum.
   ✗ prova fraca só para completar a fileira. "3 dentistas" não é prova
     de nada; dois números fortes valem mais que três mornos.
   ============================================================ */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Diz ao navegador em que tema a página vive. Sem isto, os controles
     que o SISTEMA desenha — barra de rolagem, menu de <select>, campo de
     data — saem no tema claro do sistema operacional e destoam da página.
     `light dark` porque os dois kits têm seções claras e escuras: o
     navegador escolhe pelo fundo de cada contexto. */
  color-scheme: light dark;
  /* O alvo da âncora `#conteudo` não pode colar no topo da tela. */
  scroll-padding-top: var(--e8);
}

/* --- Toque ------------------------------------------------
   `manipulation` desliga o duplo-toque-para-ampliar nos elementos de
   ação. O efeito colateral bom é o que interessa: sem esperar o segundo
   toque, o navegador para de segurar o clique por ~300ms, e o botão
   responde na hora. Ampliar com dois dedos continua funcionando — só o
   duplo-toque sai, e só em cima de botão e link.

   Isso vale para tudo que se toca. */
a, button, [role="button"], summary, label, input, select, textarea {
  touch-action: manipulation;
}

/* Já o realce de toque — aquele retângulo cinza que o Android pinta sobre
   o elemento tocado — só sai de onde TEMOS retorno próprio.

   Tirar de todo link seria uma troca ruim: `.rodape-link` e `.mapa-link`
   não têm `:active`, e ficariam sem confirmação nenhuma no celular. O
   realce do sistema é feio, mas feio é melhor que mudo. */
.botao, button, [role="button"] { -webkit-tap-highlight-color: transparent; }

/* E para os links que não são botão, o retorno próprio, para o realce do
   sistema virar dispensável também neles. */
a:not(.botao):active { opacity: 0.7; }
/* --- Movimento reduzido ---------------------------------
   Reduzir não é desligar. A regra antiga zerava TODA transição, e com
   ela o retorno que confirma uma ação: o botão mudava de cor num salto,
   sem dizer que reagiu ao toque.

   O que some é o MOVIMENTO ESPACIAL — animação e transform. O que fica
   é a mudança de cor e de sombra, curta o bastante para não parecer
   lentidão e longa o bastante para o olho registrar que algo respondeu. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-property: color, background-color, border-color, box-shadow, opacity, outline-color !important;
    transition-duration: 90ms !important;
  }
}

body {
  margin: 0;
  font-size: var(--texto-base);
  line-height: var(--altura-corpo);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, video { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4 { margin: 0; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }

/* --- Blocos de tipografia ------------------------------- */
.display {
  font-size: var(--texto-xl);
  line-height: var(--altura-display);
  letter-spacing: var(--letra-display);
  font-weight: 600;
}
.titulo {
  font-size: var(--texto-lg);
  line-height: var(--altura-titulo);
  letter-spacing: var(--letra-titulo);
  font-weight: 600;
}
.sobrelinha {
  font-size: var(--texto-micro);
  letter-spacing: var(--letra-micro);
  text-transform: uppercase;
  font-weight: 600;
}
.conduz { font-size: var(--texto-base); line-height: 1.55; }
@media (min-width: 48rem) { .conduz { font-size: var(--texto-md); line-height: 1.5; } }

@media (min-width: 48rem) {
  .display { font-size: var(--texto-3xl); }
  .titulo  { font-size: var(--texto-2xl); }
}

/* --- Estrutura ------------------------------------------ */
.pagina { max-width: var(--largura-pagina); margin-inline: auto; padding-inline: var(--respiro-lateral); }
.prosa  { max-width: var(--largura-texto); }
.secao  { padding-block: var(--e16); }
@media (min-width: 48rem) { .secao { padding-block: var(--e24); } }

/* --- Hero ------------------------------------------------
   Tela cheia, não faixa. Hero de 200px foi o erro dos primeiros
   mockups: vira cartãozinho e a foto deixa de ser o design.         */
.hero {
  position: relative;
  min-height: 88svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  isolation: isolate;
}
.hero-fundo {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  /* O corte padrão quase nunca serve: a parte boa da foto costuma estar
     fora do centro. Ajustar por alvo com --foco na camada 3.          */
  object-position: var(--foco, 50% 50%);
  /* Ken Burns: entrega a sensação de vídeo por 200 KB em vez de 6 MB.
     A própria Suganuma perde 35 pontos de PageSpeed pelo vídeo real.  */
  animation: kenburns 28s ease-in-out infinite alternate;
}
@keyframes kenburns {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.07) translate3d(-1%, -1%, 0); }
}
/* Sem esta camada, texto sobre foto é ilegível em metade das fotos. */
.hero-veu { position: absolute; inset: 0; z-index: -1; }

/* --- Grades: a última linha nunca fica órfã ---------------
   `repeat(auto-fit, minmax(...))` deixa a LARGURA decidir o número de
   colunas, então quem escreve o CSS não controla a última linha. Com
   contagem fixa de itens, aparece órfão em alguma largura — e o pior é
   que muda qual. Medido na página da Patrícia, com 4 itens em três
   grades: em 1440px sobrava 1 nos depoimentos; em 1100px, na galeria e
   nos depoimentos; em 900px, nos serviços e na galeria. Em toda largura
   de desktop havia pelo menos uma grade quebrada.

   A correção é parar de deixar a largura decidir: o número de colunas é
   declarado, e só assume valores que DIVIDEM a contagem de itens.

     .grade-2 → 2, 1
     .grade-3 → 3, 1       (pula o 2: 3 itens em 2 colunas deixa órfão)
     .grade-4 → 4, 2, 1    (pula o 3)
     .grade-6 → 3, 2, 1    (6 é o único que sobrevive a tudo)

   Escolha a classe pela contagem. 5 itens não tem classe porque não tem
   solução: só 5 ou 1 coluna dividem 5, e 5 colunas não cabe.           */
.grade { display: grid; gap: var(--e8); grid-template-columns: 1fr; }
@media (min-width: 40rem) {
  .grade-2, .grade-4, .grade-6 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 56rem) {
  .grade-3 { grid-template-columns: repeat(3, 1fr); }
  .grade-6 { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 68rem) {
  .grade-4 { grid-template-columns: repeat(4, 1fr); }
}

/* --- Botões ---------------------------------------------- */
.botao {
  display: inline-flex; align-items: center; gap: var(--e2);
  padding: var(--e4) var(--e8);
  font-size: var(--texto-base); font-weight: 600;
  text-decoration: none; border: 1px solid transparent;
  border-radius: var(--raio-m);
  transition: transform var(--transicao), background-color var(--transicao), border-color var(--transicao);
  min-height: 48px; /* alvo de toque confortável no celular */
}
.botao:active { transform: translateY(1px); }

/* --- Acessibilidade -------------------------------------- */
:focus-visible { outline: 3px solid currentColor; outline-offset: 3px; }
.so-leitor {
  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 que nunca aparece e inutil. Ao receber foco ele sai
   do esconderijo e vira um botao de verdade, no canto superior esquerdo.
   Herda cor do contexto, entao serve em qualquer kit. */
.so-leitor:focus-visible {
  position: fixed; top: var(--e3); left: var(--e3); z-index: 100;
  width: auto; height: auto; margin: 0; clip: auto; overflow: visible;
  padding: var(--e3) var(--e6);
  /* --sobre-escuro e --tinta existem nos DOIS kits, entao o atalho sai
     legivel em qualquer um sem o layout precisar saber dele. */
  background: var(--sobre-escuro, #fff); color: var(--tinta, #111);
  border-radius: var(--raio-m);
  font-size: var(--texto-peq); font-weight: 600; text-decoration: none;
}

/* --- Hero dividido: a segunda forma ----------------------
   Metade com o texto, metade com a foto. Existe porque foto de celular
   raramente sustenta texto por cima: o véu que dá contraste come
   justamente o que a foto tinha de bom.
   Aqui a foto não carrega texto, então dispensa véu e pode ser recortada
   só na parte boa. É o padrão das páginas de saúde de maior orçamento.

   No celular empilha: foto em faixa no topo (a pessoa vê o lugar), painel
   com o texto logo abaixo, sem precisar rolar. */
.hero-dividido {
  display: grid;
  grid-template-rows: 38svh auto;
  min-height: 88svh;
  isolation: isolate;
}
.hero-dividido .hero-painel {
  display: flex; flex-direction: column; justify-content: center;
  padding-block: var(--e12);
}
.hero-dividido .hero-imagem {
  width: 100%; height: 100%; object-fit: cover;
  object-position: var(--foco, 50% 50%);
}

@media (min-width: 60rem) {
  .hero-dividido {
    grid-template-rows: none;
    grid-template-columns: 1.05fr 0.95fr;
  }
  /* No desktop o texto vem primeiro na leitura, então inverte a ordem visual */
  .hero-dividido .hero-painel { order: -1; padding-block: var(--e24); }
}

/* ============================================================
   REVELAR — o CSS que o revelar.js aciona

   Quatro formas de entrada, não uma. As duas skills batem no mesmo
   ponto: a MESMA entrada em toda seção é a marca registrada de página
   gerada. Aqui cada bloco entra do jeito que o conteúdo dele pede.

   Tudo depende da classe `revela` no <html>, posta pelo próprio script.
   Sem script, sem classe, e a página fica inteira visível — que é o
   comportamento certo quando algo falha.
   ============================================================ */

.revela [data-revelar] {
  opacity: 0;
  transition:
    opacity 800ms cubic-bezier(0.16, 1, 0.3, 1) var(--atraso, 0ms),
    transform 800ms cubic-bezier(0.16, 1, 0.3, 1) var(--atraso, 0ms),
    clip-path 900ms cubic-bezier(0.16, 1, 0.3, 1) var(--atraso, 0ms);
  will-change: opacity, transform;
}

/* Sobe. O padrão, para bloco de texto e lista.
   40px e não 14: deslocamento pequeno demais não se vê. */
.revela [data-revelar="subir"]   { transform: translateY(40px); }
/* Entra de lado. Para o que acompanha uma coluna. */
.revela [data-revelar="lado"]    { transform: translateX(-32px); }
/* Aproxima. Para número e dado, que devem parecer assentar. */
.revela [data-revelar="escala"]  { transform: scale(0.94); }
/* Cortina. Para foto: a imagem é DESCOBERTA, não deslizada.

   O clip vai na IMAGEM DE DENTRO, nunca no elemento observado — e isso
   não é detalhe. `clip-path: inset(0 0 100% 0)` zera a área de
   interseção, então o IntersectionObserver nunca considera o elemento
   visível, nunca dispara, e o clip nunca sai. Armadilha circular: a
   foto some para sempre, e com `loading="lazy"` o arquivo nem chega a
   ser pedido. */
.revela [data-revelar="cortina"] { opacity: 1; will-change: auto; }
.revela [data-revelar="cortina"] img {
  clip-path: inset(0 0 100% 0);
  transition: clip-path 900ms cubic-bezier(0.16, 1, 0.3, 1) var(--atraso, 0ms);
}
.revela [data-revelar="cortina"].revelado img { clip-path: inset(0 0 0 0); }

/* Foco. Para galeria: a foto ENTRA EM FOCO, como uma câmera ajustando —
   começa desfocada e levemente ampliada, e assenta nítida. Escolhido pelo
   Daniel (02/10) no lugar da cortina, que na galeria lia como brusca.

   Mesma regra da cortina: o efeito vai na IMAGEM, nunca no elemento
   observado, senão o observador mede um bloco invisível. A figura corta
   a sobra da ampliação (overflow), e o foco termina antes da escala —
   a nitidez chega primeiro, o assentamento continua um pouco depois,
   que é o que faz parecer lente e não zoom. */
/* A dica de camada vai na FOTO, que é quem anima — no bloco ela só
   criava uma camada à toa (vale para a cortina também). */
.revela [data-revelar="foco"] { opacity: 1; overflow: hidden; will-change: auto; }
.revela [data-revelar="foco"] img {
  opacity: 0;
  transform: scale(1.06);
  filter: blur(8px);
  will-change: opacity, transform, filter;
  transition:
    opacity 1100ms cubic-bezier(0.22, 1, 0.36, 1) var(--atraso, 0ms),
    filter 1100ms cubic-bezier(0.22, 1, 0.36, 1) var(--atraso, 0ms),
    transform 1600ms cubic-bezier(0.22, 1, 0.36, 1) var(--atraso, 0ms);
}
.revela [data-revelar="foco"].revelado img { opacity: 1; transform: none; filter: none; }

.revela [data-revelar].revelado {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0);
  will-change: auto;
}

/* Escalonamento: irmãos entram na tela juntos, então o atraso tem que
   ser declarado. Não existe escalonamento automático. */
.revela [data-atraso="1"] { --atraso: 90ms; }
.revela [data-atraso="2"] { --atraso: 180ms; }
.revela [data-atraso="3"] { --atraso: 270ms; }
.revela [data-atraso="4"] { --atraso: 360ms; }
