/* ==========================================================================
   L'INSTANT — base
   Depende de tokens.css. Ver PLANO.md secção 06 para a fundamentação.
   ========================================================================== */

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink-body);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--green-deep);
  margin: 0 0 var(--space-md);
  text-wrap: balance;
}
h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-lg); }
p  { margin: 0 0 var(--space-md); max-width: var(--measure); }

a { color: var(--green-deep); text-underline-offset: 2px; }  /* 6,47:1 */
a:focus-visible,
:focus-visible { outline: 2px solid var(--green); outline-offset: 3px; border-radius: var(--radius-sm); }

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

/* O itálico de omissão do <address> nunca é o que se quer aqui: era desligado
   com style= em /contactos/ e /fr/contact/, e com uma regra à parte no rodapé. */
address { font-style: normal; }

.salta {
  position: absolute; left: -9999px;
  background: var(--green); color: var(--on-green);
  padding: var(--space-sm) var(--space-md); border-radius: 0 0 var(--radius-sm) 0;
}
.salta:focus { left: 0; top: 0; z-index: 100; }

/* --- Botões --- */
.botao {
  display: inline-block; text-decoration: none; cursor: pointer;
  font-family: var(--font-display); font-weight: var(--weight-medium);
  padding: var(--space-sm) var(--space-lg);
  border-radius: var(--radius-pill); border: 1px solid transparent;
  transition: background var(--duration-sm) var(--ease), color var(--duration-sm) var(--ease);
}
.botao--primario { background: var(--green); color: var(--on-green); }
.botao--primario:hover { background: var(--green-deep); }
.botao--grande { padding: var(--space-md) var(--space-xl); font-size: var(--text-lg); }

.ligacao {
  font-family: var(--font-display); font-weight: var(--weight-medium);
  display: inline-flex; align-items: center; min-height: 44px;
}

/* --- Cabeçalho --- */
.cabecalho { border-bottom: 1px solid var(--rule-soft); background: var(--ground); }
.cabecalho__interior {
  max-width: var(--measure-wide); margin: 0 auto;
  padding: var(--space-md) var(--space-lg);
  display: flex; align-items: center; gap: var(--space-lg); flex-wrap: wrap;
}
/* Variante horizontal 4,51:1. Mínimo medido: 32px de altura.
   flex-shrink: 0 e max-width: none no <img> não são zelo: a 375px a linha do
   cabeçalho não cabia, o <a> era o único item com folga para encolher e o
   `img { max-width: 100% }` da base esmagava o logótipo para 48px de largura
   com os 32px de altura intactos — 4,51:1 renderizado a 1,5:1. O logótipo
   nunca se deforma; se a linha não couber, é outra coisa que cede. */
.cabecalho__logo { flex: 0 0 auto; }
.cabecalho__logo img { height: 40px; width: auto; max-width: none; }
.cabecalho__nav { display: flex; gap: var(--space-lg); flex-wrap: wrap; flex: 1; }
.cabecalho__nav a {
  font-family: var(--font-display); font-size: var(--text-sm);
  text-decoration: none; color: var(--ink-body);
  /* Alvo de toque: >=44px de altura, com a caixa a crescer por padding
     em vez de por tamanho de letra. */
  display: inline-flex; align-items: center; min-height: 44px;
}
.cabecalho__nav a:hover { color: var(--green-deep); }
/* Entre as 48rem e as 72rem a linha do cabeçalho é apertada: a 1024px sobram
   383px para a nav e os quatro destinos portugueses pedem 391 com os gaps de
   32 — 8px, e a nav passava a duas linhas. Com 20px de gap pede 355 e cabe.
   Abaixo de ~1000px continua a mudar de linha, e é o comportamento certo:
   encurtar mais o espaço entre destinos aproximava-os do limite de toque.
   O bloco de ≤48rem, mais abaixo, repõe gap: 0 no painel empilhado. */
@media (max-width: 72rem) {
  .cabecalho__nav { gap: var(--space-md); }
}
.cabecalho__acoes { display: flex; align-items: center; gap: var(--space-md); }
.idioma {
  font-size: var(--text-sm); text-decoration: none; color: var(--ink-muted);
  border: 1px solid var(--rule); border-radius: var(--radius-pill);
  padding: var(--space-xs) var(--space-md);
  display: inline-flex; align-items: center; min-height: 44px;
}
.idioma:hover { color: var(--green-deep); border-color: var(--green-deep); }
/* Só uma das duas cópias da pastilha é visível de cada vez. A da barra é a de
   omissão; a do painel entra na media query estreita. Ver a nota em header.njk.
   O seletor leva .cabecalho__nav à frente por especificidade e não por gosto:
   a pastilha do painel é um <a> dentro da nav, e `.cabecalho__nav a` (0,1,1)
   ganhava a `.idioma--painel` (0,1,0) — as duas cópias apareciam em desktop. */
.cabecalho__nav .idioma--painel { display: none; }

/* Rótulos responsivos no cabeçalho. Sem isto, as páginas francesas
   transbordavam 5px a 375px: «Português» tem uma letra a mais que
   «Français» e o cabeçalho estava no limite. */
.so-estreito { display: none; }
.sr-apenas {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* --- Secções --- */
.secao {
  max-width: var(--measure-wide); margin: 0 auto;
  padding: var(--section-y) var(--space-lg);
}
.secao__titulo { font-size: var(--text-2xl); }

/* Carril de título.
   A 1280px o contentor tem 1216px úteis, mas o texto corrido para em 68ch
   (~610px): metade da secção ficava vazia à direita e o texto lia-se como uma
   fita colada à margem esquerda. Aqui o título recua para um carril estreito e
   o corpo encosta à direita — o ar fica ENTRE os dois, que é onde se lê como
   composição e não como falha. O corpo continua a parar nos 68ch: alargá-lo
   para preencher píxeis custaria legibilidade.
   :has() em vez de uma classe nova porque o alvo se descreve exatamente pelo
   conteúdo — «secção com título e corpo de texto» — e assim não é preciso
   marcar as páginas uma a uma, nos dois idiomas. Grelhas de imagens e as
   faixas centradas (--cta, --prova, --statement) não têm .prosa/.passos/
   .problemas como filho direto e ficam de fora por construção. */
/* 72rem e não 64rem. Estas grelhas reservam --measure (686px) para o texto e
   dão o resto à outra coluna. A 1024px sobravam 202px: os títulos quebravam em
   colunas de duas palavras e, em /sobre/, o retrato da Sarah colapsava para
   222px ao lado de 686px de texto — a desproporção que estas regras existem
   para corrigir, ao contrário. A 1152px sobram 330px, que chegam para as duas
   coisas. Abaixo disso vale o empilhamento simples, que a esses tamanhos lê
   melhor do que uma coluna esmagada. */
@media (min-width: 72rem) {
  .secao--carril {
    display: grid;
    /* O carril é 1fr e não uma largura fixa: com 13rem, «E se o problema não
       estivesse apenas no cabelo?» quebrava em cinco linhas de duas palavras.
       Assim a coluna do título recebe todo o resto da largura e é o max-width
       em ch que decide onde o texto quebra — a caixa é larga, a linha é curta.
       A coluna do corpo fica encostada à direita, com o ar entre as duas. */
    grid-template-columns: minmax(0, 1fr) minmax(0, var(--measure));
    column-gap: var(--space-2xl);
    align-items: start;
  }
  .secao--carril > .secao__titulo { grid-column: 1; margin: 0; max-width: 19ch; }
  .secao--carril > :not(.secao__titulo) { grid-column: 2; }
}

/* Secção que é só texto corrido, sem .secao__titulo para pôr em carril (o H2
   vive dentro da própria .prosa). Um bloco de 610px encostado à esquerda de
   1216px lê-se como erro de layout; centrado, o ar fica simétrico dos dois
   lados e lê-se como margem. */
@media (min-width: 72rem) {
  .secao:has(> .prosa:only-child) > .prosa { margin-inline: auto; }
}

.secao--statement {
  text-align: center;
  padding-block: var(--space-3xl);
}
.statement {
  font-family: var(--font-display); font-size: var(--text-xl);
  line-height: var(--leading-snug); color: var(--green-deep);
  max-width: 46ch; margin-inline: auto;
}
/* Filete de sálvia acima da frase. Dá-lhe o ar de citação de abertura em vez
   de parágrafo perdido no meio de um campo vazio. */
.statement::before {
  content: ""; display: block; width: 3rem; height: 2px;
  background: var(--sage); margin: 0 auto var(--space-lg);
}

.secao--prova { text-align: center; padding-block: var(--section-y); }
.prova__nota { font-size: var(--text-lg); color: var(--ink-body); margin-inline: auto; }
.prova__nota strong { font-family: var(--font-display); font-size: var(--text-2xl); color: var(--green); }

/* Faixa de CTA. Estava em --surface (#F6F5F1) sobre --ground (#EAE5E1): 1,05:1
   de luminância, ou seja, invisível como faixa. --sand é a cor de alternância
   do sistema e destaca-se de facto; --ink-body dá 5,6:1 e --green-deep 6,0:1
   por cima dela. */
.secao--cta {
  text-align: center; background: var(--sand);
  border-radius: var(--radius-lg);
  padding-block: var(--space-3xl);
}
.secao--cta p { margin-inline: auto; }
.secao--cta > :last-child { margin-bottom: 0; }

/* --- Hero ---
   O véu que garantia contraste destruía a fotografia: duas camadas somadas
   davam 0,82 de alfa sobre TODA a metade esquerda, de cima a baixo, e o rosto
   da fotografia está exatamente aí. Media-se o contraste e perdia-se a imagem.
   A saída é não pôr texto por cima de fotografia: o texto passa para um cartão
   opaco assente no canto inferior esquerdo. O contraste deixa de depender da
   imagem (é o mesmo do corpo do site, 6,06:1) e o véu reduz-se a um esbatido
   leve, só para assentar o cartão. */
.hero { position: relative; }
/* <picture> é inline por omissão. Como bloco de contenção do véu absoluto,
   um elemento inline forma o bloco a partir das caixas em linha, o que varia
   entre motores. display:block torna o comportamento determinista. */
.hero__imagem { display: block; }
/* Altura explícita em vez de max-height. Com max-height: 62vh a imagem nunca
   era limitada em ecrãs estreitos — 2400×1350 a 375px de largura dá 211px de
   altura natural, muito abaixo dos 503px do limite, e o hero ficava uma nesga
   letterbox. Com height + object-fit: cover é o recorte que se adapta. */
.hero__imagem img {
  width: 100%; height: clamp(15rem, 38vh, 20rem);
  object-fit: cover; object-position: 50% 38%;
}
/* A home tem um letreiro — um logótipo construído — dentro da fotografia, e a
   altura do hero é uma clamp de vh: a mesma imagem recorta-se de maneira
   diferente em cada proporção de janela. A 1280×900 os 42% assentavam bem; a
   1558×784 cortavam o topo das letras. Ancorada ao topo, o letreiro entra
   sempre inteiro e é o chão do balcão que cede — que é o que se pode perder.
   As restantes fotos de hero não têm texto e continuam nos 38/42%. */
.hero__imagem--marca img { object-position: 50% 0%; }
.hero__texto {
  max-width: var(--measure-wide);
  /* O cartão sobe para dentro da imagem: fecha a costura entre os dois blocos
     e evita a faixa morta que havia entre a foto e o texto. */
  margin: calc(var(--space-xl) * -1) auto 0;
  padding: var(--space-lg);
  position: relative;
}
.hero__cartao {
  background: var(--surface);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-lg);
  padding: var(--space-xl);
  box-shadow: var(--shadow-card);
}
.hero__cartao > :last-child { margin-bottom: 0; }
.hero__cartao h1 { margin-bottom: var(--space-sm); }
.hero__sub {
  font-size: var(--text-lg); color: var(--ink-body);
  max-width: 26ch; margin-bottom: var(--space-lg);
}

@media (min-width: 48rem) {
  .hero__imagem img { height: clamp(20rem, 52vh, 30rem); }
  .hero__texto { margin-top: calc(var(--space-2xl) * -1); }
}

@media (min-width: 64rem) {
  .hero__imagem { position: relative; }
  .hero__imagem img { height: clamp(30rem, 74vh, 40rem); object-position: 50% 42%; }
  .hero__imagem--marca img { object-position: 50% 0%; }
  /* Esbatido leve, verde-escuro e não preto, para manter o registo da marca.
     0,34 no rodapé da imagem contra os 0,82 anteriores: já não é o véu que
     garante a leitura do texto, é o cartão. */
  .hero__imagem::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(to top,
      rgba(24, 32, 27, 0.34) 0%,
      rgba(24, 32, 27, 0.14) 34%,
      rgba(24, 32, 27, 0) 66%);
  }
  .hero__texto {
    position: absolute; inset: auto 0 0 0;
    margin: 0 auto; padding-bottom: var(--space-2xl);
  }
  .hero__cartao {
    max-width: 34rem;
    padding: var(--space-xl) var(--space-xl) var(--space-lg);
  }
}

/* --- Dois caminhos ---
   Eram duas imagens 4/5 soltas: a 582px de largura davam 727px de altura para
   legendar duas linhas de texto. Passam a cartões — a imagem em 5/4 (466px) e
   o texto num corpo com filete em volta, para o conjunto se ler como uma
   unidade em vez de uma foto gigante com uma frase debaixo. */
.caminhos { display: grid; gap: var(--space-lg); grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr)); }
.caminho {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--rule-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
  padding-bottom: var(--space-lg);
  box-shadow: var(--shadow-card);
}
.caminho img {
  aspect-ratio: 5 / 4; object-fit: cover; width: 100%;
  margin: 0 0 var(--space-lg);
}
.caminho > :not(img):not(picture) { margin-inline: var(--space-lg); }
.caminho h3 { margin-bottom: var(--space-sm); }
.caminho p { max-width: none; }
/* Empurra a ligação para o fundo do cartão: com textos de comprimento
   diferente, os dois «Saber mais» alinham na mesma linha. */
.caminho .ligacao { margin-top: auto; }

/* --- Rodapé --- */
.rodape { background: var(--footer-bg); color: var(--on-green); margin-top: var(--section-y); }
.rodape a { color: var(--on-green); }
/* Colunas explícitas em vez de auto-fit: com auto-fit a coluna do logótipo
   recebia o mesmo peso das outras três e sobrava-lhe meio metro de ar, ao
   mesmo tempo que «Seguir» e «Legal» ficavam empilhados na mesma coluna. */
.rodape__interior {
  max-width: var(--measure-wide); margin: 0 auto;
  padding: var(--space-2xl) var(--space-lg);
  display: grid; gap: var(--space-xl);
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
}
/* Fora da grelha, o PRR ocupa a largura toda: se ficasse como mais uma coluna
   do auto-fit, a barra descia para ~216px. */
.rodape__interior > .prr { grid-column: 1 / -1; }

/* Quatro colunas e DUAS linhas. O bloco PRR ocupa a segunda linha à esquerda —
   exatamente o ar morto que sobrava por baixo do logótipo e da tabela de
   horários, que acabam bem antes dos contactos e do legal. Os blocos que
   atravessam as duas linhas continuam inteiros. Como faixa à largura toda no
   fundo, o PRR valia 282px dos 812px do rodapé; aqui não acrescenta altura
   nenhuma. */
@media (min-width: 64rem) {
  .rodape__interior {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-template-areas:
      "marca horarios contactos seguir"
      "prr   prr      prr       seguir";
    column-gap: var(--space-lg);
    row-gap: var(--space-lg);
    align-items: start;
  }
  /* O crédito de autoria alinha em baixo pela barra do PRR, do outro lado da
     grelha. A coluna «seguir» atravessa as duas linhas e o PRR ocupa a segunda:
     esticar a coluna e empurrar o último elemento com margin-top:auto põe as
     duas arestas inferiores na mesma linha, em vez de deixar o crédito a
     flutuar onde o texto acima calhar acabar.
     O align-self é preciso porque a grelha usa align-items:start — é isso que
     faz as colunas pararem onde o conteúdo acaba, e é isso que aqui se
     dispensa, só nesta. */
  .rodape__bloco--seguir { align-self: stretch; display: flex; flex-direction: column; }
  .rodape__bloco--seguir > .rodape__autoria { margin-top: auto; }

  .rodape__bloco--marca     { grid-area: marca; }
  .rodape__bloco--horarios  { grid-area: horarios; }
  .rodape__bloco--contactos { grid-area: contactos; }
  .rodape__bloco--seguir    { grid-area: seguir; }
  .rodape__interior > .prr  { grid-area: prr; }
}

/* A barra tem de medir 480px. Encaixada em DUAS de quatro colunas, isso exige
   2×coluna + goteira >= 480, ou seja um contentor de 992px, ou seja um ecrã de
   1056px; a 1024px dava 464px e o emblema da UE caía para 0,94 cm. Por isso
   entre 64rem e 68rem o PRR ocupa TRÊS colunas, e só a partir de 68rem
   (1088px, que deixa 496px com folga de arredondamento) recolhe para duas e
   liberta a coluna dos contactos para descer. */
@media (min-width: 68rem) {
  .rodape__interior {
    grid-template-areas:
      "marca horarios contactos seguir"
      "prr   prr      contactos seguir";
  }
}
.rodape__titulo {
  font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: var(--tracking-caps); color: var(--on-green-muted);
  margin-bottom: var(--space-sm);
}
/* Lockup completo: mínimo medido 200px de largura, para o descritor se ler. */
.rodape__logo { width: 220px; height: auto; }
.rodape__lista { list-style: none; padding: 0; margin: 0 0 var(--space-lg); }
.rodape__lista li { margin-bottom: 0; }
/* 44px por linha (WCAG 2.5.5, nível AAA) esticava cada lista a quase o dobro
   da tabela de horários ao lado e era daí que vinha metade dos 956px do
   rodapé. 34px cumpre com folga o critério que de facto se aplica — 2.5.8,
   AA, 24×24px — e o ritmo das quatro colunas volta a bater. As ligações de
   ação (telefone, WhatsApp, email) ficam nos 44px: essas são alvos de toque
   a sério. */
.rodape__lista a { display: inline-flex; align-items: center; min-height: 34px; }
.rodape address a { display: inline-flex; align-items: center; min-height: 44px; }
.rodape__nota { font-size: var(--text-sm); color: var(--on-green-muted); margin-top: var(--space-md); }
/* A margem inferior de 20px que o <p> traz de omissão é altura a mais no fim
   de um bloco. Deu para ver no crédito de autoria: punha a coluna da marca em
   208px, sete acima dos 201px da tabela de horários ao lado, e como é a
   primeira linha da grelha que manda, o rodapé inteiro crescia 7px em todas as
   páginas. Mesmo idioma que .hero__cartao, .destaque e .secao--cta já usam. */
.rodape__bloco > :last-child,
.rodape__nota:last-child { margin-bottom: 0; }
/* Empilhado, a folga vem da margem inferior da lista legal que fica por cima —
   o mesmo intervalo que separa as outras listas do rodapé. Em desktop é a regra
   de alinhamento mais abaixo que manda. */
.rodape__autoria { margin-top: 0; }
.horarios { border-collapse: collapse; font-size: var(--text-sm); }
.horarios th { text-align: left; font-weight: var(--weight-regular); padding-right: var(--space-md); }
.horarios th, .horarios td { padding-block: 2px; }
.horarios__fechado { color: var(--on-green-muted); }

/* --- PRR ---
   A frase e o URL formam um bloco só, colados, porque é essa a menção
   obrigatória (ver PRR/Content/Texto obrigatório PRR). A barra de logótipos
   vem a seguir. Antes o URL aparecia DEPOIS da barra e lia-se como um crédito
   solto do rodapé, sem relação visível com a frase que legenda. */
.prr {
  padding-top: var(--space-lg);
  border-top: 1px solid rgba(255, 255, 255, 0.22);
}
.prr__frase { font-size: var(--text-sm); color: var(--on-green-muted); margin: 0; max-width: none; }
.prr__link { font-size: var(--text-sm); margin: 0; }
/* 34px e não 44: a 44px abria-se um degrau entre a frase e o URL que os fazia
   ler como dois elementos independentes. Cumpre a WCAG 2.5.8 (AA, 24×24px);
   os 44px ficam reservados às ligações de ação do rodapé. */
.prr__link a { display: inline-flex; align-items: center; min-height: 34px; }
/* 30rem = 480px é o MÍNIMO, não uma preferência: o emblema da União Europeia
   ocupa 53,2% da altura da barra (medido no ficheiro, 74px de 139px), pelo que
   a 480px de largura fica com 37px — o 1 cm que a identidade visual do
   financiamento exige. Nunca reduzir. */
.prr img { width: min(30rem, 100%); height: auto; margin: var(--space-md) 0 0; }

.aviso-revisao {
  background: #F4E7C8; color: #6B5518; text-align: center;
  padding: var(--space-xs) var(--space-lg); font-size: var(--text-sm);
  border-bottom: 1px solid #E0CFA4;
}

/* --- Marcador de conteúdo por traduzir ---
   Visível de propósito: impede que texto estrutural passe por copy aprovado.
   Remover quando a fase 2 fechar. */
[data-estado="por-traduzir"] {
  background: repeating-linear-gradient(45deg, #F4E7C8, #F4E7C8 8px, #EFE0BC 8px, #EFE0BC 16px);
  color: #6B5518; border-radius: var(--radius-sm);
  padding: var(--space-xs) var(--space-sm);
}

/* --- Menu mobile: <details>, sem JavaScript ---
   Empilhado, o cabeçalho ocupava 262px de um ecrã de 812px — 32% antes de
   qualquer conteúdo. Recolhido, fica em ~93px. */
.menu__botao {
  display: inline-flex; align-items: center; gap: var(--space-sm);
  min-height: 44px; padding: 0 var(--space-sm);
  background: none; border: 1px solid var(--rule); border-radius: var(--radius-pill);
  cursor: pointer; color: var(--ink-body);
  font-family: var(--font-display); font-size: var(--text-sm);
}
.menu__botao[hidden] { display: none; }
.menu__botao[aria-expanded="true"] { color: var(--green-deep); border-color: var(--green-deep); }
.menu__traco {
  width: 16px; height: 9px;
  border-top: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
}
/* Recolhida só quando o script o marca — nunca por omissão. */
.cabecalho__nav[data-recolhido] { display: none; }

@media (max-width: 48rem) {
  :root { --section-y: 3rem; --space-3xl: 4rem; --space-2xl: 3rem; --space-xl: 2.5rem; --text-4xl: 2.25rem; --text-2xl: 1.65rem; }

  /* Empilhado, o lede e o primeiro parágrafo ficavam a 100px um do outro
     (52 de padding do topo + 48 da secção seguinte) apesar de serem a mesma
     ideia. Em desktop não se nota porque estão em colunas diferentes. */
  .pagina-topo { padding-bottom: var(--space-md); }
  /* A linha do cabeçalho a 375px: 311px úteis (64 de goteira, a mesma das
     secções) para o logótipo por inteiro (144), o botão do menu (42) e o
     «Marcar» (85) — 287px com os dois gaps de 8. Sobram 24. Era por isto que
     o seletor de idioma teve de ir para dentro do painel: com a pastilha
     ficavam 97px a mais e não havia goteira, gap nem rótulo que os
     arranjasse. Abaixo de ~355px a linha pode mudar de linha (flex-wrap
     herdado) — cabeçalho mais alto, mas nada esmagado nem cortado. */
  .cabecalho__interior { gap: var(--space-xs); }
  .cabecalho__logo img { height: 32px; }  /* mínimo medido da variante horizontal */
  .menu__botao .menu__rotulo { display: none; }
  /* `position: absolute` sem `top` deixa a caixa na posição estática, e num
     contentor flex com align-items: center a posição estática de uma caixa
     de 249px numa linha de 84px é top: -82px: metade do painel ficava acima
     do topo do ecrã. Os dois primeiros destinos — «Spa do Cabelo» a y=-74 e
     «Cabeleireiro» a y=-30 — não se via nenhum, e as duas páginas de
     serviços ficavam inalcançáveis a partir do menu. O painel é ancorado
     ao cabeçalho, não à linha que o contém. */
  .cabecalho { position: relative; }
  .cabecalho__nav {
    position: absolute; top: 100%; left: 0; right: 0; z-index: 20;
    flex-direction: column; gap: 0;
    background: var(--ground); border-bottom: 1px solid var(--rule);
    padding: var(--space-xs) var(--space-lg) var(--space-md);
    box-shadow: 0 12px 24px rgba(58, 58, 56, 0.08);
  }
  .cabecalho__acoes { gap: var(--space-xs); }
  /* No painel a pastilha é uma linha como as outras. */
  .idioma--barra { display: none; }
  .cabecalho__nav .idioma--painel { display: inline-flex; align-self: flex-start; margin-top: var(--space-sm); }
  .cabecalho__acoes .botao { padding: var(--space-xs) var(--space-md); font-size: var(--text-sm); }
  .so-largo { display: none; }
  .so-estreito { display: inline; }
  .idioma { padding-inline: var(--space-sm); }
}


/* ==========================================================================
   Componentes de página
   ========================================================================== */

/* --- Cabeçalho de página ---
   Em desktop o primeiro ecrã de uma página interior era um H1 e duas linhas de
   texto no canto superior esquerdo, com o resto vazio: nenhuma âncora visual.
   Duas correções. O título e o lede passam a duas colunas, alinhados pela
   base, para ocuparem a largura. E a secção seguinte — que nestas páginas é
   quase sempre a fotografia de abertura — perde o padding de topo, para subir
   para dentro do primeiro ecrã em vez de ficar 136px abaixo dele. */
.pagina-topo { padding: var(--space-2xl) var(--space-lg) var(--space-xl); max-width: var(--measure-wide); margin: 0 auto; }
.pagina-topo h1 { max-width: 20ch; }
.pagina-topo .lede { font-size: var(--text-lg); color: var(--ink-body); max-width: 54ch; margin-bottom: 0; }
/* Só quando a secção seguinte ABRE com imagem. A regra existia para puxar a
   fotografia de abertura para dentro do primeiro ecrã; aplicada a tudo,
   colava o lede ao primeiro parágrafo da secção seguinte quando esse
   parágrafo cai na mesma coluna — em /sobre/ liam-se como um bloco só. */
.pagina-topo + .secao:has(> picture, > .figura) { padding-top: 0; }

@media (min-width: 72rem) {
  /* A coluna do lede é --measure, a mesma de .secao--carril: assim o lede
     arranca exatamente no eixo em que arranca todo o texto das secções
     abaixo. Com 34rem ficava 66px à direita desse eixo — perto o suficiente
     para se ler como desalinhamento e não como decisão. */
  .pagina-topo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, var(--measure));
    column-gap: var(--space-2xl);
    align-items: end;
  }
  .pagina-topo > .migalhas { grid-column: 1 / -1; }
  .pagina-topo > h1 { grid-column: 1; margin-bottom: 0; }
  .pagina-topo > .lede { grid-column: 2; }
}

/* Fotografia solta numa secção, com ou sem <figure> em volta. Em 2400×1350 a
   1216px de largura dava 684px de altura — mais do que todo o resto do
   primeiro ecrã junto. O raio vem daqui e não de um style= repetido em cada
   página: era o mesmo valor de token escrito à mão em quatro ficheiros. */
.secao > picture > img,
.secao > .figura > img { max-height: 30rem; object-fit: cover; width: 100%; border-radius: var(--radius-md); }
.migalhas { font-size: var(--text-sm); color: var(--ink-muted); margin-bottom: var(--space-md); }
.migalhas a {
  color: var(--ink-muted);
  /* WCAG 2.5.8 (AA) exige alvos de 24x24px. */
  display: inline-flex; align-items: center; min-height: 24px;
}
.migalhas a:hover { color: var(--green-deep); }

/* --- Prosa --- */
.prosa { max-width: var(--measure); }
.prosa > * + * { margin-top: var(--space-md); }
.prosa h2 { margin-top: var(--space-xl); }
.prosa h3 { margin-top: var(--space-lg); }
/* As duas regras acima servem para SEPARAR um título do que vem antes. No
   primeiro filho não há nada de que o separar, e as 52rem de espaço abriam um
   degrau: em /metodo-da-raiz/, em /cabeleireiro/ e na home o H2 da coluna de
   texto arrancava 52px abaixo do topo da fotografia ao lado, quando as duas
   colunas deviam começar juntas. Nas secções de uma coluna era pior — 52px
   somados ao padding da secção, a esticar uma transição que --section-y foi
   medido para deixar nos 136px. Vinte ocorrências, catorze páginas. */
.prosa > :first-child { margin-top: 0; }

/* --- Listas de texto corrido ---
   Eram as únicas listas do site sem regra nenhuma: todas as outras (.passos,
   .marcas, .problemas, .contacto-lista, .rodape__lista) são componentes com
   list-style: none. Deixadas ao agente de utilizador, ficavam com os 40px de
   padding de omissão — o texto 40px à direita do eixo em que assentam o H2 e
   todos os parágrafos da mesma página — e com zero espaço entre itens, ao lado
   de parágrafos com 20px. Oito páginas.
   Tentou-se pendurar o marcador na goteira, como .assinatura faz, para o texto
   continuar no eixo. Não serve aqui: .assinatura só pendura a partir das 72rem
   porque abaixo disso não há goteira, e nestas listas nunca há — em
   /metodo-da-raiz/ e na home a coluna de texto é a primeira de .duas-colunas e
   está encostada à margem da página, pelo que o marcador saía para 10px da
   borda do ecrã. Um recuo é convenção editorial legítima; o que não era
   legítimo eram os 40px fora da escala. Fica --space-md, que é da escala, e o
   marcador leva --sage — a função que tokens.css lhe atribui, filetes e
   ícones, nunca texto.
   :not([class]) porque as listas com nome de componente já têm as suas regras
   e não devem herdar estas. */
.prosa ul:not([class]),
.prosa ol:not([class]) {
  margin-block: 0;
  padding-left: var(--space-md);
}
/* O :not([class]) também aqui, e não foi zelo: sem ele a regra chegava a
   .marcas — que está dentro de .prosa — e dava 12px de margem a todos os
   nomes menos ao primeiro. Numa grelha isso desce cada item 12px em relação
   ao vizinho da mesma linha, que era metade do desalinhamento que a cliente
   apontou. .prosa li + li tem mais especificidade do que .marcas li, pelo
   que o `margin: 0` do componente não se defendia sozinho. */
.prosa ul:not([class]) > li + li,
.prosa ol:not([class]) > li + li { margin-top: var(--space-sm); }
.prosa ul:not([class]) > li::marker,
.prosa ol:not([class]) > li::marker { color: var(--sage); }
.assinatura {
  font-family: var(--font-display); font-size: var(--text-lg);
  color: var(--green-deep); line-height: var(--leading-snug);
  border-left: 2px solid var(--sage); padding-left: var(--space-md);
  margin-block: var(--space-xl);
}
/* O filete fica pendurado na goteira, para que o TEXTO da citação continue no
   mesmo eixo do resto. Com o filete dentro da medida, a citação começava 22px
   à direita de todos os outros parágrafos — um degrau visível numa página que
   é toda ela texto alinhado a um eixo. */
@media (min-width: 72rem) {
  .assinatura { margin-left: calc((var(--space-md) + 2px) * -1); }
}

/* --- Serviços ---
   Uma coluna só: cada cartão ficava com 1216px de largura para um texto que
   para nos 68ch. Duas colunas a partir de 64rem. */
.servicos { display: grid; gap: var(--space-lg); }
@media (min-width: 64rem) {
  /* 28rem e não 24rem: com 24rem cabiam três colunas de ~380px e os textos
     destes cartões são longos — davam colunas estreitas e altíssimas. Duas
     colunas de ~614px é o que equilibra. */
  .servicos { grid-template-columns: repeat(auto-fit, minmax(min(28rem, 100%), 1fr)); }
}
.servico {
  background: var(--surface); border-radius: var(--radius-md);
  padding: var(--space-lg); border: 1px solid var(--rule-soft);
  box-shadow: var(--shadow-card);
  display: flex; flex-direction: column;
}
.servico .botao--linha { align-self: start; margin-top: auto; }
.servico p { max-width: none; }
.servico__cabeca { margin-bottom: var(--space-md); }
.servico__nome { margin: 0 0 var(--space-2xs); font-size: var(--text-xl); }
.servico__sub {
  font-family: var(--font-display); font-size: var(--text-sm);
  letter-spacing: var(--tracking-caps); text-transform: uppercase;
  /* --sage dá 2,35:1 e falha AA. A própria regra do sistema diz que o
     sálvia nunca serve para texto — só filetes, ícones e superfícies. */
  color: var(--ink-muted); margin: 0 0 var(--space-xs);
}
.servico__meta { font-family: var(--font-display); font-weight: var(--weight-medium); color: var(--green-deep); margin: 0; }
.servico__corpo > * + * { margin-top: var(--space-sm); }
.servico__corpo p:last-child { margin-bottom: 0; }
.botao--linha {
  background: transparent; border-color: var(--green); color: var(--green-deep);
  margin-top: var(--space-md);
}
.botao--linha:hover { background: var(--green); color: var(--on-green); }

/* --- Passos do método --- */
.passos { list-style: none; padding: 0; margin: 0; max-width: none; display: grid; gap: var(--space-lg); }
.passo { display: grid; grid-template-columns: auto 1fr; gap: var(--space-lg); align-items: start; margin: 0; }
.passo__n {
  font-family: var(--font-display); font-size: var(--text-2xl); font-weight: var(--weight-medium);
  /* --sage dá 2,35:1 e o próprio sistema de design diz que o sálvia nunca
     serve para texto — só filetes, ícones e superfícies. É o mesmo defeito
     que 86ac533 corrigiu em .servico__sub e que aqui ficou por corrigir.
     --green dá 3,70:1, que passa AA para texto grande (33,2px). */
  color: var(--green); line-height: 1; min-width: 2ch;
}
.passo__titulo { margin: 0 0 var(--space-xs); font-size: var(--text-lg); }
.passo__verbo {
  display: inline-block; font-size: var(--text-sm); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--ink-muted); margin-left: var(--space-xs);
}
.passo__corpo > * + * { margin-top: var(--space-sm); }

/* --- Frases-problema --- */
.problemas { list-style: none; padding: 0; margin: 0 0 var(--space-xl); display: flex; flex-wrap: wrap; gap: var(--space-sm); max-width: none; }
.problemas li {
  font-family: var(--font-display); font-size: var(--text-base);
  background: var(--surface); border: 1px solid var(--rule-soft);
  border-radius: var(--radius-pill); padding: var(--space-xs) var(--space-md);
  color: var(--ink-body); margin: 0;
}
.pergunta-gancho {
  font-family: var(--font-display); font-size: var(--text-xl);
  color: var(--green-deep); line-height: var(--leading-snug); max-width: 30ch;
}

/* A nota de preço sobrevive à tabela: o meta do cartão «Pack Crescimento
   Capilar» traz um <span class="preco__nota"> com o valor por sessão. O resto
   do bloco — .precos-tabela, .tabelas, .tabela-scroll — saiu com a página
   /precos/, que a cliente pediu para retirar. */
.preco__nota { display: block; font-size: var(--text-sm); color: var(--ink-muted); }

/* --- Testemunhos --- */
.testemunhos { display: grid; gap: var(--space-md); grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr)); margin-top: var(--space-xl); }
/* Sem filete, --surface sobre --ground não desenha cartão nenhum (1,05:1 de
   luminância): eram três parágrafos centrados a flutuar. E o texto passa a
   ficar à esquerda — a secção é que está centrada, as citações não. */
.testemunho {
  background: var(--surface); border: 1px solid var(--rule-soft);
  border-radius: var(--radius-md); padding: var(--space-lg); margin: 0;
  text-align: left; display: flex; flex-direction: column;
  box-shadow: var(--shadow-card);
}
.testemunho blockquote {
  margin: 0 0 var(--space-md); font-family: var(--font-display);
  font-size: var(--text-lg); line-height: var(--leading-snug);
  color: var(--green-deep);
}
.testemunho figcaption { font-size: var(--text-sm); color: var(--ink-muted); margin-top: auto; }

/* --- Marcas ---
   Grelha e não flex-wrap. Em flex cada nome ocupava a sua largura e as linhas
   quebravam onde calhava: «Compagnie des Sens · Keraplant · Lisap Milano» numa
   linha e «Lisaplex · Tea Tree · Paul Mitchell» noutra, cada uma a começar num
   x diferente. Seis nomes de comprimento desigual sem eixo comum lêem-se como
   erro de alinhamento — foi o que a cliente apontou, na página inicial e na do
   cabeleireiro. Em colunas de largura igual há um eixo por coluna. */
.marcas {
  list-style: none; padding: 0; max-width: none;
  display: grid; gap: var(--space-md) var(--space-xl);
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  align-items: start;
}
.marcas li {
  font-family: var(--font-display); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; font-size: var(--text-sm); color: var(--ink-muted); margin: 0;
}

/* --- Grelha de duas colunas --- */
.duas-colunas {
  display: grid; gap: var(--space-xl);
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  align-items: start;
}
.figura { margin: 0; }
.figura img { border-radius: var(--radius-md); }
/* A barra de logótipos do PRR é a única imagem do site que se centra em vez de
   encostar ao eixo: é um emblema de financiamento, não uma fotografia. Estava
   centrada por dois atributos de estilo em linha, um no figure e outro na
   imagem.
   E leva os cantos a esquadro. O raio de .figura img arredondava-a em 14px na
   /prr/ enquanto a MESMA barra sai a esquadro no rodapé, onde não vive dentro
   de uma .figura: o mesmo activo a renderizar de duas maneiras, e num activo
   de identidade visual obrigatória o arredondamento não é nosso para decidir. */
.figura--centro { text-align: center; }
.figura--centro img { margin-inline: auto; border-radius: 0; }
.figura figcaption { font-size: var(--text-sm); color: var(--ink-muted); margin-top: var(--space-xs); }

/* Figura + texto alinhados ao eixo do carril, para páginas onde este bloco é
   seguido de secções de texto corrido. Em 50/50 a coluna de texto arrancava
   38px ao lado do eixo dessas secções: três arestas esquerdas quase
   coincidentes lêem-se como erro de alinhamento. Aqui a coluna de texto é
   --measure e a figura fica com o resto — a mesma grelha de .secao--carril. */
@media (min-width: 72rem) {
  .duas-colunas--carril {
    grid-template-columns: minmax(0, 1fr) minmax(0, var(--measure));
  }
  /* Mínimo mais baixo do que o das outras figuras: aqui o texto ao lado é
     curto e os 22rem de omissão faziam a fotografia ultrapassá-lo em 80px,
     abrindo um degrau por baixo do último parágrafo. Assim é o texto que
     manda na altura da linha, como no resto do site. */
  .duas-colunas--carril > .figura { min-height: 18rem; }
}

/* Figura ao lado de texto: a altura vem da COLUNA DE TEXTO, não do ficheiro.
   Era aqui o pior desencontro do site. As fotos são 1067×1600 (2:3); a 570px
   de largura pedem 855px de altura, ao lado de 250 a 340px de texto — 500 a
   600px de coluna vazia por baixo do parágrafo, em cinco secções diferentes.
   Com a figura em posicionamento absoluto ela deixa de ter altura intrínseca:
   a linha da grelha é medida pelo texto e a imagem recorta-se ao que sobra,
   com um mínimo para o texto muito curto não a esmagar numa nesga.
   Nenhuma figura dentro de .duas-colunas tem legenda — as duas únicas com
   <figcaption> estão em contactos.njk e prr.njk, soltas na secção. */
@media (min-width: 48rem) {
  .duas-colunas { align-items: stretch; }
  .duas-colunas > .figura {
    position: relative; overflow: hidden;
    border-radius: var(--radius-md);
    min-height: 22rem;
  }
  .duas-colunas > .figura > picture,
  .duas-colunas > .figura > img { position: absolute; inset: 0; }
  .duas-colunas > .figura img {
    width: 100%; height: 100%; object-fit: cover;
    border-radius: 0;
  }
  /* Retratos: o enquadramento útil está acima do centro geométrico. */
  .duas-colunas > .figura img { object-position: 50% 32%; }
  /* Excepção medida, não gosto: na foto-20 a profundidade de campo é curta e
     o único plano nítido são os frascos rotulados, entre 50% e 83% da altura.
     Os 32% de omissão caíam inteiramente no desfoque — a secção «Produtos e
     valores» mostrava um borrão, e foi isso que a cliente viu. A 82% o
     recorte assenta nos frascos nítidos e na aresta da prateleira. */
  .duas-colunas > .figura--baixo img { object-position: 50% 82%; }
}

/* --- Caixa de destaque --- */
.destaque {
  background: var(--surface); border-left: 2px solid var(--green);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  padding: var(--space-lg); margin-block: var(--space-lg);
}
.destaque > :last-child { margin-bottom: 0; }
.destaque p { max-width: none; }

/* --- Dados de contacto --- */
.contacto-lista { list-style: none; padding: 0; margin: 0; max-width: none; }
.contacto-lista li { margin-bottom: var(--space-md); }
/* Estas ligações são ações autónomas, não texto corrido — a isenção da
   WCAG 2.5.8 para ligações inline não se aplica. */
.contacto-lista a { display: inline-flex; align-items: center; min-height: 44px; }
.contacto-lista strong { display: block; font-size: var(--text-sm); text-transform: uppercase; letter-spacing: var(--tracking-caps); color: var(--ink-muted); font-weight: var(--weight-semi); }
.horarios-pagina { border-collapse: collapse; width: 100%; max-width: 22rem; }
.horarios-pagina th { text-align: left; font-weight: var(--weight-regular); padding: var(--space-xs) var(--space-md) var(--space-xs) 0; border-bottom: 1px solid var(--rule-soft); }
.horarios-pagina td { text-align: right; padding: var(--space-xs) 0; border-bottom: 1px solid var(--rule-soft); font-variant-numeric: tabular-nums; }
.horarios-pagina .fechado td, .horarios-pagina .fechado th { color: var(--ink-muted); }

@media (max-width: 48rem) {
  .servico { padding: var(--space-md); }
  .passo { grid-template-columns: 1fr; gap: var(--space-sm); }
  .hero__cartao { padding: var(--space-lg); }
  .secao--cta { border-radius: var(--radius-md); }

  /* --- Rodapé empilhado ---
     1576px, 1,9 ecrãs, em todas as 22 páginas; na /prr/ era metade da página.
     O conteúdo é legítimo e os alvos de toque também, por isso o que se corta
     é o desperdício: a goteira entre blocos, o lockup completo (que empilha
     marca, nome e descritor em 146px de altura) e as listas em coluna. */
  .rodape__interior { gap: var(--space-lg); padding-block: var(--space-xl); }
  .rodape__logo { width: 172px; }
  /* Listas em linha: as quatro redes passam de quatro filas a duas, e o legal
     de quatro a três. A altura de 34px do alvo mantém-se, e a goteira de 20px
     separa-os na horizontal. */
  .rodape__lista { display: flex; flex-wrap: wrap; column-gap: var(--space-md); margin-bottom: var(--space-md); }
}
