/* ==========================================================================
   Essence Tântric — componentes.css
   Vocabulário fechado de componentes, escrito SÓ com var(--token).
   Sem um único valor literal de cor, tamanho, espaço, raio ou sombra: o que
   faz deste ficheiro um contrato e não um conjunto de regras soltas.
   Autor: DESIGNER (Coneki) · 19/09/2026
   ========================================================================== */

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

body {
  margin: 0;
  background: var(--cor-fundo);
  color: var(--cor-texto);
  font-family: var(--fonte-texto);
  font-size: var(--fs-corpo);
  font-weight: var(--peso-normal);
  line-height: var(--altura-linha-corpo);
  -webkit-font-smoothing: antialiased;
}

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

a { color: var(--cor-marca); text-decoration-thickness: 1px; text-underline-offset: 3px; }

/* Alvo de toque mínimo em QUALQUER ligação, incluindo as que vivem dentro de
   um título ou de uma linha de texto (WCAG 2.5.8, 24px). Sem isto, a ligação
   do nome no cartão compacto mede 22px — foi o que a medição apanhou. A altura
   resolve-se com min-height e a largura com min-width: um nome curto («Liz»,
   22 × 24 px; «Isa», 21 × 24) tem de dar 24 px de alvo nos dois eixos. */
h1 a, h2 a, h3 a, h4 a, .ligacao-acao, .rodape a {
  display: inline-flex;
  align-items: center;
  min-height: var(--alvo-minimo);
  min-width: var(--alvo-minimo);
}

/* Ligações no meio de uma frase (27/09/2026). A regra de cima resolve as que
   são título ou ação; as que vivem dentro de um parágrafo ficavam com a caixa
   da linha — 20 px de altura com letra de 17 px, abaixo dos 24 do contrato.
   Medido a 390 px, antes: 16 ligações em `/pt/massagem-nuru/`, 4 numa página
   cidade+serviço, 1 no telefone da página de contacto. Depois: 0.

   O `padding-block` de 3 px cresce só a área clicável e cabe na meia-entrelinha
   (3,6 px com 17 px de letra a 1,6 de altura de linha), por isso nada se move:
   medido, o transbordo continua 0 e nenhuma página mudou de altura. */
.leitura a { padding-block: 3px; }

/* Títulos: hierarquia por tamanho + peso + cor + espaço.
   Retirando a cor, a hierarquia mantém-se. */
h1, h2, h3, h4 {
  font-family: var(--fonte-display);
  font-weight: var(--peso-medio);
  line-height: var(--altura-linha-titulo);
  letter-spacing: var(--tracking-display);
  margin: 0 0 var(--esp-4);
  color: var(--cor-marca);
  text-wrap: balance;
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
h4 {
  font-size: var(--fs-corpo);
  font-family: var(--fonte-texto);
  font-weight: var(--peso-forte);
  letter-spacing: normal;
  line-height: 1.35;
}

p { margin: 0 0 var(--esp-4); max-width: var(--medida-prosa); }
p.intro { font-size: var(--fs-corpo); max-width: var(--medida-intro); color: var(--cor-texto-suave); }

/* Rótulo, etiqueta, nota legal. Único sítio onde o texto é menor que a prosa;
   abaixo de 13px não desce nada, em nenhuma página (nota legal incluída).
   Maiúsculas só em rótulos curtos: nunca em texto corrido.
   PROIBIDO usar .legenda como olho de secção acima de um título: o portão
   anti-slop conta isso como `kicker-above-heading` (7 acusações na 1.ª versão
   do especime, todas removidas). O título carrega-se a si próprio. */
.legenda {
  font-size: var(--fs-legenda);
  font-weight: var(--peso-medio);
  letter-spacing: var(--tracking-legenda);
  text-transform: uppercase;
  color: var(--cor-texto-suave);
}

.leitura { max-width: var(--medida-prosa); }

/* Foco visível em tudo o que é operável. Nunca removido. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--foco-largura) solid var(--cor-foco);
  outline-offset: var(--foco-deslocamento);
}
.fundo-escuro :focus-visible,
.faixa-legal :focus-visible,
.rodape :focus-visible {
  outline-color: var(--cor-foco-escuro);
}

/* --------------------------------------------------------------------------
   CONTENTOR E GRELHA
   Uma classe por grelha. Nunca descendente dependente da árvore.
   -------------------------------------------------------------------------- */
.limite {
  width: 100%;
  max-width: var(--largura-conteudo);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

.seccao { padding-top: var(--respiro-seccao); padding-bottom: var(--respiro-seccao); }
.seccao--creme { background: var(--cor-superficie); }

.grelha-cartoes {
  display: grid;
  gap: var(--esp-6);
  grid-template-columns: repeat(var(--colunas-cartoes-telemovel), minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 640px) {
  .grelha-cartoes { grid-template-columns: repeat(var(--colunas-cartoes-medio), minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .grelha-cartoes { grid-template-columns: repeat(var(--colunas-cartoes-desktop), minmax(0, 1fr)); }
  .seccao { padding-top: var(--esp-24); padding-bottom: var(--esp-24); }
  .limite { padding-left: var(--gutter-desktop); padding-right: var(--gutter-desktop); }
}

/* --------------------------------------------------------------------------
   BOTÃO — 3 variantes, um só primário por ecrã.
   Todos os pares ≥ 4,5:1 (ver tabela §3.4 do contrato).
   -------------------------------------------------------------------------- */
.botao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--esp-2);
  min-height: var(--altura-controlo);
  padding: var(--esp-3) var(--esp-6);
  border: 0;
  border-radius: var(--raio-controlo);
  font-family: var(--fonte-texto);
  font-size: var(--fs-corpo);
  font-weight: var(--peso-forte);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-rapida) var(--ease-padrao),
              color var(--dur-rapida) var(--ease-padrao);
}

/* primário: bordéus sobre creme — 9,54:1 */
.botao--primario { background: var(--cor-marca); color: var(--cor-texto-escuro); }
.botao--primario:hover { background: color-mix(in srgb, var(--cor-marca) 86%, var(--cor-texto)); }

/* de acento: dourado com tinta por cima — 8,98:1. É a variante do herói e das
   faixas escuras. O legado usava branco sobre dourado: 2,31:1, reprovado. */
.botao--acento { background: var(--cor-acento); color: var(--cor-texto); }
.botao--acento:hover { background: color-mix(in srgb, var(--cor-acento) 84%, var(--cor-texto)); }

/* secundário: contorno da marca sobre fundo claro — texto 11,89:1 */
.botao--secundario {
  background: transparent;
  color: var(--cor-marca);
  border: 1px solid var(--cor-marca);
}
.botao--secundario:hover { background: color-mix(in srgb, var(--cor-marca) 8%, transparent); }

.botao[aria-disabled='true'], .botao:disabled { opacity: 0.55; cursor: not-allowed; }

/* de conversa: o verde do canal, com o glifo do WhatsApp. Existe porque o dono
   pediu que a conversão passasse a ser por WhatsApp (27/09/2026) e porque o
   verde de marca do WhatsApp, #25D366, mede 1,98:1 com texto branco — reprovado,
   e é a razão pela qual o botão do próprio WhatsApp se lê mal. O degrau escuro
   da mesma família mede 5,29:1 com branco, 4,25:1 de aresta sobre o creme e
   3,57:1 sobre a tinta. Não é uma cor nova da paleta: é a cor do canal. */
.botao--conversa { background: var(--cor-conversa); color: var(--cor-fundo); }
.botao--conversa:hover { background: color-mix(in srgb, var(--cor-conversa) 84%, var(--cor-texto)); }
.botao__glifo { flex: none; width: 22px; height: 22px; }

/* A ação principal da página de contacto: 64px de altura útil, degrau de título
   no rótulo. Alvo de polegar, não de rato. */
.botao--conversa--grande {
  min-height: var(--esp-16);
  padding: var(--esp-4) var(--esp-8);
  font-size: var(--fs-h3);
}
.botao--conversa--grande .botao__glifo { width: 26px; height: 26px; }

/* Ligação de ação: mesma intenção do botão, sem peso de superfície */
.ligacao-acao {
  display: inline-flex;
  align-items: center;
  min-height: var(--alvo-minimo);
  font-weight: var(--peso-forte);
}

/* --------------------------------------------------------------------------
   CARTÃO DE MASSAGISTA — UMA linguagem (o legado tinha duas, com 30px de raio
   na home e 20px na listagem). Aresta definida, sombra 0.
   -------------------------------------------------------------------------- */
.cartao-massagista {
  display: flex;
  flex-direction: column;
  background: var(--cor-fundo);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-cartao);
  overflow: hidden;
}

.cartao-massagista__foto {
  position: relative;
  aspect-ratio: 4 / 5;
  background: var(--cor-superficie);
}
.cartao-massagista__foto img { width: 100%; height: 100%; object-fit: cover; }
/* O <picture> é só um embrulho de formatos (WebP com recurso a JPEG): não deve criar
   caixa própria dentro da moldura, senão o object-fit do img deixa de mandar. */
.cartao-massagista__foto picture { display: contents; }

/* Moldura do retrato: junta o bloco e a legenda de estado. É content-sized, para o
   cartão compacto continuar a medir o bloco (88 px com imagem, 96 px sem). */
.cartao-massagista__retrato {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  flex: none;
}

.cartao-massagista__corpo {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  padding: var(--esp-4);
}

.cartao-massagista__nome {
  font-family: var(--fonte-display);
  font-size: var(--fs-h3);
  font-weight: var(--peso-medio);
  line-height: var(--altura-linha-titulo);
  color: var(--cor-marca);
  margin: 0;
}

.cartao-massagista__zona { font-size: var(--fs-legenda); color: var(--cor-texto-suave); }
.cartao-massagista__resumo { font-size: var(--fs-legenda); color: var(--cor-texto-suave); margin: 0; }

.cartao-massagista__etiquetas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.etiqueta {
  display: inline-flex;
  align-items: center;
  min-height: var(--alvo-minimo);
  padding: var(--esp-1) var(--esp-3);
  border: 1px solid var(--cor-marca);
  border-radius: var(--raio-pilula);
  font-size: var(--fs-legenda);
  font-weight: var(--peso-medio);
  color: var(--cor-marca);
  text-decoration: none;
}

.cartao-massagista .botao { margin-top: var(--esp-2); }

/* --------------------------------------------------------------------------
   PLACA DE FOTOGRAFIA — a caixa onde uma imagem assenta
   --------------------------------------------------------------------------
   Esteve em `home.css` desde 24/09/2026 e só a home a via: o `tw.css` importa
   `home.css` no seu bundle, mas nenhuma outra página o faz. O que isso custou,
   medido ao vivo a 27/09/2026 na lista de massagistas:

     · `.placa--3x4` não tinha regra nenhuma (varrimento de classes sem regra:
       25 ocorrências, o único nome sem estilo da página);
     · a fotografia do cartão media 280,7x442,9 px onde na home media
       360,7x480,9 px — não havia `object-fit: cover`, nem proporção, nem
       `width/height: 100%`, e o `img` de base (max-width: 100%, height: auto)
       ficava com a proporção natural do ficheiro;
     · resultado à vista: o mesmo cartão de equipa parecia outro cartão.

   A placa é uma peça de interface como o retrato, a etiqueta ou o botão, e vive
   onde as outras vivem. As regras são as mesmas que estavam medidas na home —
   nada aqui foi redesenhado, só mudou de casa.
   -------------------------------------------------------------------------- */
.placa {
  margin: 0;
  border: 1px solid var(--placa-borda, var(--cor-borda));
  border-radius: var(--raio-fio);
  overflow: hidden;
  background: var(--cor-superficie);
}
.placa img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.placa--4x5 img { aspect-ratio: 4 / 5; }
.placa--3x4 img { aspect-ratio: 3 / 4; }
.placa--1x1 img { aspect-ratio: 1 / 1; }
/* O <picture> é embrulho de formatos, não caixa: o object-fit do img manda. */
.placa picture { display: contents; }

/* --------------------------------------------------------------------------
   CARTÃO DE MODALIDADE e CARTÃO DE ARTIGO — mesma família, densidade maior
   -------------------------------------------------------------------------- */
.cartao-modalidade, .cartao-artigo {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  padding: var(--esp-6);
  background: var(--cor-superficie);
  border-radius: var(--raio-cartao);
}
.cartao-artigo { background: var(--cor-fundo); border: 1px solid var(--cor-borda); }
.cartao-modalidade h3, .cartao-artigo h3 { margin-bottom: 0; }
.cartao-modalidade p, .cartao-artigo p { font-size: var(--fs-corpo); color: var(--cor-texto-suave); margin: 0; max-width: var(--medida-prosa); }

/* --------------------------------------------------------------------------
   CABEÇALHO
   -------------------------------------------------------------------------- */
.cabecalho {
  background: var(--cor-marca);
  color: var(--cor-texto-escuro);
}
.cabecalho__linha {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-6);
  min-height: 72px;
  padding-top: var(--esp-3);
  padding-bottom: var(--esp-3);
}
.cabecalho__marca {
  font-family: var(--fonte-display);
  font-size: var(--fs-h3);
  font-weight: var(--peso-medio);
  color: var(--cor-texto-escuro);
  text-decoration: none;
  letter-spacing: var(--tracking-display);
}
.cabecalho__menu { display: flex; flex-wrap: wrap; gap: var(--esp-6); margin: 0; padding: 0; list-style: none; }
.cabecalho__menu a {
  display: inline-flex;
  align-items: center;
  min-height: var(--alvo-minimo);
  color: var(--cor-texto-escuro);
  font-size: var(--fs-legenda);
  font-weight: var(--peso-medio);
  text-decoration: none;
}
.cabecalho__menu a[aria-current='page'] {
  color: var(--cor-texto-escuro);
  border-bottom: var(--foco-largura) solid var(--cor-acento);
}

/* --------------------------------------------------------------------------
   HERÓI — marca e proposta visíveis no primeiro ecrã a 390px.
   Nada de camada fixa a tapar o topo (decisão do contrato, §5.1).
   -------------------------------------------------------------------------- */
.heroi { background: var(--cor-marca); color: var(--cor-texto-escuro); }
.heroi__interior {
  display: flex;
  flex-direction: column;
  gap: var(--esp-4);
  padding-top: var(--esp-16);
  padding-bottom: var(--esp-16);
}
.heroi__titulo {
  font-family: var(--fonte-display);
  font-size: var(--fs-display);
  font-weight: var(--peso-medio);
  line-height: var(--altura-linha-display);
  letter-spacing: var(--tracking-display);
  color: var(--cor-texto-escuro);
  margin: 0;
  text-wrap: balance;
}
.heroi__apoio { color: var(--cor-texto-escuro); max-width: var(--medida-intro); margin: 0; }
.heroi .legenda { color: var(--cor-acento); }
.heroi__accoes { display: flex; flex-wrap: wrap; gap: var(--esp-4); align-items: center; }

/* --------------------------------------------------------------------------
   PROVA SOCIAL, FAIXA LEGAL, FORMULÁRIO, RODAPÉ
   -------------------------------------------------------------------------- */
.resenha {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  padding: var(--esp-4);
  background: var(--cor-fundo);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-cartao);
}
.resenha__texto { font-size: var(--fs-corpo); color: var(--cor-texto); margin: 0; }
.resenha__autor { font-size: var(--fs-legenda); color: var(--cor-texto-suave); margin: 0; }

.faixa-legal {
  background: var(--cor-fundo-escuro);
  color: var(--cor-texto-escuro-suave);
  padding-top: var(--esp-4);
  padding-bottom: var(--esp-4);
  font-size: var(--fs-legenda);
}

.campo { display: flex; flex-direction: column; gap: var(--esp-2); }
.campo__rotulo { display: inline-flex; align-items: center; min-height: var(--alvo-minimo); font-size: var(--fs-legenda); font-weight: var(--peso-medio); }
.campo__entrada {
  min-height: var(--altura-controlo);
  padding: var(--esp-3) var(--esp-4);
  background: var(--cor-fundo);
  color: var(--cor-texto);
  border: 1px solid var(--cor-borda-controlo);
  border-radius: var(--raio-controlo);
  font-family: var(--fonte-texto);
  font-size: var(--fs-corpo);
}
.campo__erro { font-size: var(--fs-legenda); color: var(--cor-marca); }
.campo__ajuda { font-size: var(--fs-legenda); color: var(--cor-texto-suave); max-width: var(--medida-prosa); }

/* Nota corrida: frase inteira, logo degrau de corpo e medida de prosa.
   O portão de tipografia mede >= 60 caracteres como prosa e exige 16px+. */
.nota { font-size: var(--fs-corpo); color: var(--cor-texto-suave); max-width: var(--medida-prosa); margin: 0; }
.nota-escura { font-size: var(--fs-corpo); color: var(--cor-texto-escuro-suave); max-width: var(--medida-prosa); margin: 0; }

.rodape { background: var(--cor-fundo-escuro); color: var(--cor-texto-escuro); }
.rodape__grelha {
  display: grid;
  gap: var(--esp-8);
  grid-template-columns: 1fr;
  padding-top: var(--esp-12);
  padding-bottom: var(--esp-12);
}
@media (min-width: 768px) { .rodape__grelha { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.rodape h4 { color: var(--cor-texto-escuro); }
.rodape a { color: var(--cor-texto-escuro); min-height: var(--alvo-minimo); display: inline-flex; align-items: center; }
.rodape p { color: var(--cor-texto-escuro-suave); }
.rodape li { color: var(--cor-texto-escuro-suave); font-size: var(--fs-legenda); }
.rodape ul { margin: 0; padding: 0; list-style: none; }

/* Aviso de consentimento: faixa no fim do documento, não camada sobre o herói.
   Sem cor de plugin: creme da marca, aresta definida, zero sombra difusa. */
.consentimento {
  border-top: 1px solid var(--cor-borda);
  background: var(--cor-superficie);
  padding-top: var(--esp-4);
  padding-bottom: var(--esp-4);
}
.consentimento__interior { display: flex; flex-wrap: wrap; gap: var(--esp-4); align-items: center; justify-content: space-between; }
.consentimento p { margin: 0; font-size: var(--fs-corpo); color: var(--cor-texto-suave); max-width: var(--medida-prosa); }
.consentimento__accoes { display: flex; flex-wrap: wrap; gap: var(--esp-4); }
/* A faixa nasce `hidden` no HTML e é o script que a revela (28/09/2026): quem
   navega sem JavaScript não fica com uma barra morta à frente. A regra é
   declarada porque uma classe com `display` ganharia ao atributo. */
.consentimento[hidden] { display: none; }

/* --------------------------------------------------------------------------
   CABEÇALHO EM TELEMÓVEL — o legado escondia a marca atrás de avisos e tinha
   um menu de 21px de altura. Aqui: marca sempre no primeiro ecrã, menu num
   painel que abre por baixo da barra (nunca camada fixa sobre o conteúdo) e
   item de menu com 48px de altura útil.
   -------------------------------------------------------------------------- */
.cabecalho__painel { display: contents; }
.cabecalho__botao {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-2);
  min-height: var(--alvo-minimo);
  padding: var(--esp-2) var(--esp-4);
  border: 1px solid var(--cor-texto-escuro);
  border-radius: var(--raio-controlo);
  color: var(--cor-texto-escuro);
  font-size: var(--fs-legenda);
  font-weight: var(--peso-forte);
  cursor: pointer;
  list-style: none;
}
.cabecalho__botao::-webkit-details-marker { display: none; }

/* Em telemóvel o menu vive FORA do <details> (é o irmão a seguir): com o painel
   aberto abre por baixo da barra, a largura toda, e a barra não cresce — a marca
   fica ancorada no topo. Com o painel fechado o menu não ocupa linha nenhuma. */
@media (max-width: 767px) {
  .cabecalho__linha { flex-wrap: wrap; align-items: flex-start; }
  .cabecalho__painel { display: block; }
  .cabecalho__painel + nav { display: none; flex-basis: 100%; }
  .cabecalho__painel[open] + nav { display: block; }
  .cabecalho__menu {
    flex-direction: column;
    gap: 0;
    padding-top: var(--esp-3);
    padding-bottom: var(--esp-2);
  }
  .cabecalho__menu a {
    display: flex;
    min-height: var(--esp-12);
    font-size: var(--fs-corpo);
    border-bottom: 1px solid color-mix(in srgb, var(--cor-texto-escuro) 24%, transparent);
  }
}

@media (min-width: 768px) {
  .cabecalho__botao { display: none; }
}

/* --------------------------------------------------------------------------
   CARTÃO COMPACTO — a listagem em telemóvel.
   O legado punha 22 cartões de retrato numa só coluna: 20 733 px de lista a
   390px (27,6 ecrãs). A densidade muda no telemóvel: retrato pequeno, nome e
   zona; o resumo e as etiquetas ficam na ficha.
   -------------------------------------------------------------------------- */
.grelha-cartoes--lista { gap: var(--esp-3); }

.cartao-massagista--compacto {
  flex-direction: row;
  align-items: center;
  gap: var(--esp-4);
  padding: var(--esp-3);
  text-decoration: none;
}
.cartao-massagista--compacto .cartao-massagista__foto {
  flex: 0 0 88px;
  width: 88px;
  aspect-ratio: 1 / 1;
  border-radius: var(--raio-controlo);
  overflow: hidden;
}
.cartao-massagista--compacto .cartao-massagista__corpo { padding: 0; gap: var(--esp-1); }
.cartao-massagista--compacto .cartao-massagista__nome {
  font-family: var(--fonte-texto);
  font-size: var(--fs-corpo);
  font-weight: var(--peso-forte);
}
.cartao-massagista--compacto .cartao-massagista__zona { font-size: var(--fs-legenda); }
.cartao-massagista--compacto .cartao-massagista__resumo,
.cartao-massagista--compacto .cartao-massagista__etiquetas { display: none; }

@media (min-width: 640px) {
  .grelha-cartoes--lista { gap: var(--esp-6); }
  .cartao-massagista--compacto { flex-direction: column; align-items: stretch; padding: 0; }
  .cartao-massagista--compacto .cartao-massagista__foto {
    flex: 1 1 auto;
    width: 100%;
    aspect-ratio: 4 / 5;
    border-radius: 0;
  }
  .cartao-massagista--compacto .cartao-massagista__corpo { padding: var(--esp-4); gap: var(--esp-2); }
  .cartao-massagista--compacto .cartao-massagista__nome {
    font-family: var(--fonte-display);
    font-size: var(--fs-h3);
  }
  .cartao-massagista--compacto .cartao-massagista__resumo,
  .cartao-massagista--compacto .cartao-massagista__etiquetas { display: flex; }
}

/* O herói respira: no desktop leva o respiro de secção completo */
@media (min-width: 1024px) {
  .heroi__interior { padding-top: var(--esp-24); padding-bottom: var(--esp-24); }
}

/* Só no telemóvel: blocos de demonstração da densidade móvel */
.so-telemovel { display: none; }
@media (max-width: 639px) { .so-telemovel { display: block; } }

/* --------------------------------------------------------------------------
   ESTADO «SEM FOTOGRAFIA» — o retrato só tem 4:5 quando existe imagem.
   Sem imagem não se desenha uma caixa vazia: o bloco passa a 1:1 (96 a 120 px de
   lado, sobre creme), com o monograma da marca centrado e fio de aresta, e a
   legenda a 13 px por baixo. Fica no FIM do ficheiro de propósito: estas regras
   têm de vencer as das densidades, em qualquer largura. Contrato, adenda de
   21/09/2026 — a versão anterior servia 2 444 blocos vazios em 354 páginas.
   -------------------------------------------------------------------------- */
.cartao-massagista__foto--sem-imagem,
.cartao-massagista--compacto .cartao-massagista__foto--sem-imagem {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 var(--esp-24);
  width: var(--esp-24);
  aspect-ratio: 1 / 1;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-controlo);
  overflow: hidden;
}

.cartao-massagista__monograma {
  font-family: var(--fonte-display);
  font-size: var(--fs-h2);
  font-weight: var(--peso-medio);
  line-height: 1;
  color: var(--cor-marca);
}

.cartao-massagista__legenda {
  font-size: var(--fs-legenda);
  color: var(--cor-texto-suave);
  margin: 0;
}

/* --------------------------------------------------------------------------
   Galeria de fotografias (Fase 2, 22/09/2026)

   A ficha de uma massagista tem até 16 fotografias e a página do espaço tem 10.
   Regras que a grelha respeita:
     - proporção da fotografia preservada (a galeria mostra a imagem inteira);
     - alturas alinhadas por linha, para a grelha não ficar em escada: as linhas
       do grid são iguais e a imagem preenche o quadro com `object-fit: cover`;
     - três colunas no desktop, duas no tablet, uma no telemóvel — a mesma
       gramática do resto do site (`--gutter`, `--raio-cartao`);
     - sem sombra difusa: aresta de 1px, como os cartões.
-------------------------------------------------------------------------- */
.galeria {
  list-style: none;
  margin: var(--esp-8) 0 0;
  padding: 0;
  display: grid;
  gap: var(--gutter);
  grid-template-columns: repeat(var(--galeria-colunas, 3), minmax(0, 1fr));
}

.galeria__item { margin: 0; }

.galeria__ligacao {
  display: block;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio-cartao);
  overflow: hidden;
  aspect-ratio: 3 / 4;
  background: var(--cor-superficie);
}

.galeria__ligacao img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.galeria__ligacao:focus-visible {
  outline: 2px solid var(--cor-marca);
  outline-offset: 3px;
}

@media (max-width: 1023px) {
  .galeria { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 639px) {
  .galeria { grid-template-columns: minmax(0, 1fr); }
  .galeria__ligacao { aspect-ratio: 4 / 5; }
}

/* Marca no rodapé: imagem clara sobre o fundo escuro do rodapé. */
.rodape__marca { display: block; margin-bottom: var(--esp-6); }
.rodape__marca img { width: 170px; height: auto; display: block; }
