/* Âmago — página de Serviços.
   ---------------------------------------------------------------------------------------
   Duas partes: a CAPA (a secção principal, que faz aqui o que o hero faz na página
   inicial) e a GRELHA dos treze serviços, um a um, com um fecho a chamar ao contacto.

   O desenho da grelha foi escolhido pelo cliente a 2026-09-25 de entre quatro que viu num
   artefacto, e chama-se "Janelas". O diagnóstico que lá levou, medido: com containers
   opacos, eles tapavam 72% do ecrã numa janela de 1600x900 e 84% numa de 1366x768 — e a
   malha, que é a ideia da página, só existia nas sobras (tiras de 26px entre eles). Pior:
   a onda do clique, a interação de que ele gostou primeiro, era invisível precisamente
   onde se clicaria, porque viaja pela malha e a malha estava por trás das tampas.

   Aqui o container não tem fundo: fica o fio a delimitá-lo e a malha corre por dentro
   dele. O contraste do texto é segurado por um VÉU COM A FORMA DO TEXTO — forte no canto
   onde ele vive, a apagar-se para o canto oposto, que fica com a malha limpa.

   As classes da capa vão prefixadas `capa-*` e não `servicos-*` de propósito: a secção é a
   mesma para qualquer página interior que venha a querer uma, e a Sobre e a Notícias hão
   de querer. Quando a segunda aparecer, essa parte muda de ficheiro.
   ========================================================================================= */

/* A página é BRANCA e a barra fica opaca desde o topo: as duas regras vivem no `base.css`
   (`.pagina-clara`), partilhadas com a página de Notícias. O template pede-as pela classe
   do `<body>`. O rodapé traz o seu próprio fundo escuro e fecha a página, como em todas. */

/* ---------------------------------------------------------------- a malha, e as suas opções
   Tudo o que o `rede.js` lê está aqui, num sítio só. As duas cores são as mesmas da
   secção "Serviços" da homepage; o resto são as opções do modo PÁGINA, que a homepage não
   declara e por isso não usa. Os valores vêm dos afinadores do artefacto, onde o cliente
   os parou. */
.pagina-servicos{
  --rede-tinta:2,36,37;                /* a tinta da malha: o verde da marca */
  --rede-pulso:15,143,122;             /* o que nela se acende: o verde-água */
  /* A FORÇA das ligações em repouso, em múltiplos do valor de origem (2026-09-24: "as
     linhas de fundo estão muito opacas"). A 2,2 ficam em 22% de tinta, o mesmo peso que
     os PONTOS já tinham — a rede lê-se como uma malha e não como pontos com fios quase
     invisíveis entre eles. */
  --rede-forca:2.2;
  /* Quanto a malha ACOMPANHA o scroll. A 100 andava colada à página; a 40 arrasta-se
     atrás dela e lê-se como estando mais longe do que o conteúdo. */
  --rede-scroll:40;
  /* Quanto se CALA na zona de leitura (a grelha, via `data-zona` no canvas). A malha é
     uma imagem e não uma textura: em cima tem o ecrã todo e vêem-se polígonos inteiros;
     entre os cartões é picada e sobra ruído, precisamente onde há mais para ler. Fica
     cheia onde não há nada a ler e cala-se onde há. */
  --rede-calma:65;
  /* A ONDA DO CLIQUE: velocidade, quanto empurra e até onde vai (em % da diagonal). */
  --rede-onda:500;
  --rede-onda-forca:25;
  --rede-onda-longe:170;
  position:relative;z-index:1;
}

/* Um só canvas, preso à janela, por trás de tudo. Os pontos é que são gerados sobre a
   altura toda do documento — ver o modo `data-rede="pagina"` no `rede.js`. Decoração
   pura: sem `pointer-events`, para o cursor passar direto ao que está por cima. */
.pagina-rede{position:fixed;inset:0;width:100%;height:100%;z-index:0;pointer-events:none}

/* ---------------------------------------------------------------- a capa */
/* Mede um ecrã MENOS a navbar, como o hero da homepage: é a conta certa para a PRIMEIRA
   secção de uma página, que vem logo a seguir à barra no fluxo e com ela soma um ecrã.
   (Numa secção do meio a conta é outra — ver o `.fecho` e o `.convite` no `home.css`.) */
.capa{position:relative;z-index:1;
  min-height:calc(100svh - var(--altura-nav));
  display:grid;place-items:center;
  padding:var(--respiro) clamp(16px,4vw,40px);
  overflow:hidden}

/* O véu: um clarão branco que limpa o miolo e deixa a malha nas margens e nos cantos.
   O primeiro número é o raio HORIZONTAL — é ele que aproxima ou afasta a malha das
   letras; o segundo é o VERTICAL, e o terceiro par é onde a elipse está centrada.

   São DOIS clarões sobrepostos e não um, e essa é a parte que interessa. O pedido do
   cliente foi feito com um traçado a vermelho por cima de uma captura: uma forma larga em
   cima, à volta do título, a estreitar num pescoço até ao sinal no pé da capa. Uma elipse
   só não sabe fazer isso — ou fica curta e deixa uma faixa de malha ENTRE o título e o
   sinal (cada um com o seu clarão e nada no meio), ou estica e vira uma coluna central,
   que foi o que se experimentou a seguir e ele chumbou: "ficou um vazio branco enorme".

   Dois gradientes numa lista de fundos resolvem-no, porque se somam onde se cruzam: um
   LARGO E BAIXO à volta do título, outro ESTREITO E ALTO em baixo, que sobe do sinal até
   apanhar o primeiro. A união dos dois é a forma que ele desenhou — e o branco só existe
   onde há alguma coisa para proteger, que é o que distingue um véu de um buraco. */
.capa-veu{position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(ellipse 32% 26% at 50% 48%,
      #fff 0%,#fff 56%,rgba(255,255,255,.88) 78%,rgba(255,255,255,0) 100%),
    radial-gradient(ellipse 18% 30% at 50% 86%,
      #fff 0%,#fff 52%,rgba(255,255,255,.85) 76%,rgba(255,255,255,0) 100%)}

.capa-texto{position:relative;z-index:1;display:grid;justify-items:center;
  gap:clamp(14px,2.2vh,26px);text-align:center}

/* Escrito em minúsculas no HTML e posto em maiúsculas aqui: em capitais no texto, um
   leitor de ecrã arrisca-se a soletrá-lo letra a letra — é a mesma escolha do nome dos
   projetos e da localidade do rodapé. O `balance` reparte as linhas em comprimentos
   parecidos quando ele quebra, que é o que acontece num ecrã estreito. */
.capa-titulo{margin:0;max-width:18ch;text-wrap:balance;text-transform:uppercase;
  font-weight:200;letter-spacing:.01em;line-height:1.05;
  /* A MESMA medida do <h1> do hero da página inicial (`--tipo-h1`, no `base.css`): são o
     mesmo papel — a afirmação que abre uma página — e não há razão para diferirem. Aqui
     estiveram em 70px e lá em 54px, e ninguém tinha decidido isso; divergiram sozinhos.
     Cheguei a pô-los em 130px por causa da proporção com a frase de baixo (uma palavra só
     é estreita e a frase ficava quase tão larga como ela) e o cliente chumbou à vista —
     "ficou colossal". Tinha razão duas vezes: o passo era grande demais, e a coerência
     entre páginas vale mais do que o rácio dentro de uma. */
  font-size:var(--tipo-h1)}

/* O sinal de que há mais por baixo, no pé da capa. Pequeno e esbatido de propósito: a
   frase do título é que tem de ficar com a atenção, e isto é uma nota de rodapé do ecrã.
   A seta respira devagar — o movimento é o que o olho apanha na periferia, e é por isso
   que ele funciona sem precisar de dizer "deslize". */
/* ARMADILHA que a frase mais longa destapou (2026-09-25): com `left:50%` e sem `right`,
   um elemento absoluto só tem para si a METADE DIREITA do pai — num ecrã de 390 ficava
   com 195px e a frase quebrava em duas linhas sem que faltasse espaço nenhum. Com
   `left:0;right:0` tem a largura toda e centra-se pelo `justify-items`. Não se notava
   enquanto o texto foi curto. */
.capa-desce{position:absolute;left:0;right:0;bottom:clamp(16px,4vh,40px);
  z-index:1;padding:0 clamp(16px,4vw,40px);
  /* Encolhe ao conteúdo e centra-se com as margens automáticas. O `left:0;right:0` fica
     para lhe dar a LARGURA DISPONÍVEL (ver a armadilha acima); é o `fit-content` que faz
     a caixa medir o texto, e é disso que o véu precisa para o poder seguir. */
  width:fit-content;margin-inline:auto;
  display:grid;justify-items:center;gap:7px;
  color:inherit;text-decoration:none;opacity:.5;transition:opacity .25s}
.capa-desce:hover,.capa-desce:focus-visible{opacity:1}
/* O VÉU do sinal: o mesmo clarão que limpa a malha por trás do título, à escala desta
   linha. Sem ele as linhas passam por trás de um texto que já é pequeno e esbatido, e
   é aí que ele menos aguenta concorrência. Vive num pseudo-elemento ABSOLUTO — dentro de
   uma grelha, um `::before` normal seria mais um item e empurrava o conteúdo. */
.capa-desce::before{content:'';position:absolute;inset:-22px -52px;pointer-events:none;
  background:radial-gradient(ellipse 58% 62% at 50% 50%,
    #fff 0%,#fff 54%,rgba(255,255,255,.86) 76%,rgba(255,255,255,0) 100%)}
.capa-desce > *{position:relative;z-index:1}
.capa-desce span{font-size:11px;font-weight:400;letter-spacing:.2em;text-transform:uppercase}
.capa-desce svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round;
  animation:capa-desce 2.6s ease-in-out infinite}
@keyframes capa-desce{
  0%,62%,100%{transform:translateY(0)}
  32%{transform:translateY(5px)}
}
@media (prefers-reduced-motion:reduce){
  .capa-desce svg{animation:none}
}

/* Onde o salto do sinal da capa ATERRA. Sem isto o alvo encosta ao topo do DOCUMENTO e
   a navbar, que é `sticky`, tapa-lhe os primeiros 70px — a primeira fila de cartões
   chegava cortada por cima. A margem desconta a barra e ainda deixa um respiro.

   É do ALVO e não do gesto, por isso serve os dois caminhos: o scroll suave do
   `ancoras.js` e o salto instantâneo de quem não tem JavaScript.

   O SUAVE está no `ancoras.js` e não aqui. Chegou a estar, num `html{scroll-behavior:
   smooth}`, e trouxe um defeito que o cliente apanhou: essa propriedade apanha todos os
   scrolls do browser, restauração da posição ao recarregar incluída, e a página passou a
   voar do topo até onde tinha ficado. */
#os-servicos{scroll-margin-top:calc(var(--altura-nav) + clamp(26px,5.5vh,56px))}
/* E vale para CADA container, que desde 2026-09-25 tem âncora própria: quem chega da
   grelha da homepage vem com ela no endereço e é o BROWSER a rolar — que respeita isto do
   mesmo modo, sem passar pelo `ancoras.js`. O respiro é menor do que o da grelha: ali o
   alvo é o princípio de uma secção, aqui é o topo de um cartão, e um cartão que aterre
   demasiado abaixo da barra deixa o de cima a espreitar como se fosse esse o escolhido. */
.servico{scroll-margin-top:calc(var(--altura-nav) + clamp(12px,2.2vh,24px))}

/* ---------------------------------------------------------------- a grelha dos serviços
   Dois por linha E dois por fila no mesmo ecrã: a altura de cada cartão é metade do que
   sobra da janela depois da barra, do vão e das margens. É uma conta e não um número —
   muda com a janela e continua a dar sempre 2x2. */
.servicos-grelha{--vao:clamp(14px,1.8vw,26px);
  position:relative;z-index:1;
  max-width:1320px;margin:0 auto;
  padding:0 clamp(14px,3vw,34px) clamp(60px,10vh,120px);
  display:grid;grid-template-columns:repeat(2,1fr);gap:var(--vao)}

/* São TREZE serviços, e treze é ímpar: o último ficaria sozinho a meia largura, com o
   lado direito vazio, o que se lê como um erro. Ocupa a linha toda. */
.servico:last-child:nth-child(odd){grid-column:1/-1}
/* E aí o parágrafo atravessa o cartão de uma ponta à outra, sem o limite de medida de
   linha que os outros têm. Escolha do cliente, feita com as duas à frente: o texto parava
   a meio do cartão (o `max-width:52ch`, que existe para proteger a leitura) e experimentou-
   se reparti-lo por duas colunas, que usavam a largura e mantinham a medida — chumbou à
   vista ("fica estranho e feio, mete seguido"). Fica registado o preço, que é real: a
   linha passa dos ~52 caracteres dos outros cartões para ~140. O que o torna suportável
   é o texto ficar em três linhas só — há poucos regressos ao início da linha, que é onde
   uma medida longa custa. Se um dia incomodar, a outra saída é este cartão deixar de
   ocupar a linha toda e ficar a meia largura como os outros, com o lado vazio. */
.servico:last-child:nth-child(odd) p{max-width:none}

.servico{--brilho:0;
  position:relative;
  min-height:calc((100svh - var(--altura-nav) - var(--vao) - clamp(24px,5vh,56px)) / 2);
  /* SEM fundo: é isto que faz do container uma janela e não uma tampa. O fio a verde
     escuro e não num cinzento claro (pedido do cliente a 2026-09-24): sobre o branco e
     com a malha a passar por trás, um fio cinzento perdia-se. */
  border:1px solid var(--fundo);border-radius:16px;
  padding:clamp(22px,2.6vw,38px);
  /* O ÍCONE e o TÍTULO na MESMA linha, e não empilhados (2026-09-25, pergunta do cliente:
     "ficava melhor ter os títulos à frente do ícone?"). Ficava, e a razão é medível: o
     cabeçalho deixa de gastar duas linhas de altura e passa a gastar uma. Numa janela de
     1600x900 a folga entre o texto e o fio do "Saber mais" passa de 13px para 51px; numa
     de 1366x768 o cartão encolhe de 352 para 326px e o 2x2 POR ECRÃ volta a caber (700px
     de duas filas contra 698 disponíveis) — que era exatamente o que os textos do cliente,
     30% mais longos do que os de exemplo, tinham custado. E nenhum título passa a quebrar:
     o mais comprido de todos está no 13.º cartão, que ocupa a linha toda.

     Três filas: o cabeçalho, o texto, e uma terceira em `1fr` que empurra o "Saber mais"
     para o fundo — faz o que o `margin-top:auto` fazia no flex. */
  display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto auto 1fr;
  column-gap:14px;row-gap:clamp(10px,1.4vh,16px);align-items:center;
  /* O RATO acende o contorno do cartão que está debaixo dele: o halo por fora e um anel
     de 1px por cima do fio. Em `box-shadow` e não a trocar a cor da borda, para nada ficar
     inválido quando o brilho é zero. O `--brilho` é escrito pelo `rede.js`, via o
     `data-acende` do canvas — a onda do clique NÃO lhe toca, de propósito: ela atravessa
     a malha, que é onde se lê como onda. */
  box-shadow:0 0 calc(var(--brilho) * 26px) rgba(var(--rede-pulso), calc(var(--brilho) * .42)),
             inset 0 0 0 1px rgba(var(--rede-pulso), var(--brilho))}

/* O VÉU com a forma do texto: quase opaco no canto onde ele vive e a apagar-se para o
   canto oposto, que fica com a malha limpa. Vive num pseudo-elemento e não no fundo do
   cartão precisamente para ter FORMA em vez de ser um retângulo — é isso que tira ao
   container o ar de caixa. Mesma ideia do véu do título da capa, à escala do cartão. */
.servico::before{content:'';position:absolute;inset:0;border-radius:inherit;
  pointer-events:none;
  background:radial-gradient(ellipse 108% 86% at 38% 38%,
    rgba(255,255,255,.97) 0%,rgba(255,255,255,.95) 46%,
    rgba(255,255,255,.58) 74%,rgba(255,255,255,0) 100%)}
.servico > *{position:relative;z-index:1}

/* A CHEGADA de fora: quem vem de um cartão da grelha da homepage aterra NESTE container,
   e num arranjo 2x2 o do lado fica exatamente à mesma altura — sem nada a distingui-los,
   não se sabe qual é o que se pediu. O `:target` acende o anel do rato e apaga-o em 2,4s:
   fica uma chegada e não uma moldura permanente, que é o que o cliente já recusou na lista
   das notícias ("lia-se como uma caixa de formulário").

   Vive num pseudo-elemento próprio e anima OPACIDADE — não o `--brilho` do cartão, por
   duas razões: esse é escrito pelo `rede.js` no estilo do elemento, e um valor inline ganha
   sempre a uma regra da folha; e uma variável não registada não se interpola, salta de um
   fotograma para o outro. Assim o realce do rato continua a funcionar por baixo deste. */
.servico::after{content:'';position:absolute;inset:-1px;z-index:2;
  border-radius:inherit;pointer-events:none;opacity:0;
  box-shadow:0 0 26px rgba(var(--rede-pulso),.38),
             inset 0 0 0 2px rgba(var(--rede-pulso),.5)}
.servico:target::after{animation:servico-chegada 2.4s ease-out}
@keyframes servico-chegada{0%{opacity:0}14%{opacity:1}100%{opacity:0}}
/* Com movimento reduzido o anel fica QUIETO e aceso enquanto a âncora estiver no endereço:
   a informação é a mesma — é este o serviço que se pediu — e um clarão a pulsar é
   precisamente o que essa preferência manda não fazer. */
@media (prefers-reduced-motion:reduce){
  .servico:target::after{animation:none;opacity:1}
}

.servico-icone{grid-area:1/1;width:36px;height:36px;fill:none;stroke:currentColor;
  stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.servico h2{grid-area:1/2;margin:0;
  font-size:clamp(18px,1.6vw,24px);font-weight:400;line-height:1.2;
  letter-spacing:.01em;text-wrap:balance}
/* O texto e o fecho atravessam as duas colunas: só o cabeçalho é que se reparte. */
.servico p{grid-area:2/1/3/-1;align-self:start;margin:0;max-width:52ch;
  font-size:clamp(14px,1.12vw,17px);font-weight:300;line-height:1.66;
  color:rgba(2,36,37,.66)}

/* O pé do cartão, agora só nos que LEVAM a algum lado — o GEMAX, por enquanto. É um link
   a sério e não decoração: sublinha-se ao passar o rato, alcança-se pelo teclado e abre
   noutro separador, como os outros links externos do site. */
.servico-fecho{grid-area:3/1/4/-1;align-self:end;
  display:flex;align-items:center;gap:8px;width:fit-content;
  padding-top:12px;color:inherit;text-decoration:none;
  font-size:13px;font-weight:400;letter-spacing:.02em}
.servico-fecho span,.servico-fecho{transition:opacity .2s}
.servico-fecho:hover,.servico-fecho:focus-visible{text-decoration:underline;
  text-underline-offset:4px;text-decoration-thickness:1px}
.servico-fecho svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}

/* ---- A ENTRADA PELO ÍCONE ---------------------------------------------------------
   O `--sai` (1 = ícone grande ao meio, 0 = ícone no lugar) é escrito pelo
   `entrada-cartoes.js` a cada quadro — é o ÚNICO que precisa disso, porque o caminho do
   ícone é o que se quer ver. O valor de REPOUSO é o de omissão, por isso sem JavaScript ou
   com movimento reduzido o cartão está feito desde o princípio e esta regra não faz nada.
   A chegada do TEXTO é uma transição do CSS — ver mais abaixo, e o porquê.

   O caminho do ícone até ao meio (`--dx`/`--dy`) é medido pelo script: depende do tamanho
   do cartão e do padding, que mudam com a janela. */
.servico{--sai:0;--dx:0px;--dy:0px}
.servico-icone{transform-origin:50% 50%;
  transform:translate(calc(var(--dx) * var(--sai)), calc(var(--dy) * var(--sai)))
            scale(calc(1 + 2.4 * var(--sai)))}
/* A CHEGADA DO CONTEÚDO é uma transição do CSS e não um número reescrito a cada quadro.
   Esteve assim e o cliente apanhou-o: "o fade vem meio travado". Não era falta de
   desempenho — medidos 164 quadros por segundo e zero perdidos. Era o TEXTO a ser
   deslocado com o JavaScript: 10px ao longo de 1,6s dá 6px por segundo, e a cada quadro
   as letras caíam numa fração de pixel diferente e voltavam a ser rasterizadas. Lê-se
   como tremido por muito depressa que a página vá.

   Entregue ao browser, ele promove os elementos a uma camada própria durante a transição:
   o texto é desenhado UMA vez e o resto é composição. Também encurtou, de 1,6s para 0,9s
   — um fade de texto mais longo do que isso lê-se como hesitação.

   Quem esconde é a classe `com-js`, posta no <head> por uma linha de script: sem
   JavaScript nada disto existe e o cartão está feito desde o princípio. Tem de ser no
   <head> e não no script do fim da página — medido, o browser pinta duas vezes antes
   desse correr, e o texto aparecia e desaparecia. A transição vive no estado `cheio`,
   senão esconder animava o conteúdo a DESAPARECER, à vista. */
.com-js .servico h2,
.com-js .servico p,
.com-js .servico .servico-fecho{opacity:0;transform:translateY(10px)}
.com-js .servico.cheio h2,
.com-js .servico.cheio p,
.com-js .servico.cheio .servico-fecho{opacity:1;transform:none;
  transition:opacity .9s ease, transform .9s cubic-bezier(.2,.7,.3,1)}
/* Com movimento reduzido o script sai antes de armar seja o que for, e a classe `cheio`
   nunca chega: sem esta saída, o conteúdo ficava escondido para sempre a quem pede menos
   movimento — exatamente as pessoas a quem não se pode fazer isso. */
@media (prefers-reduced-motion:reduce){
  .com-js .servico h2,
  .com-js .servico p,
  .com-js .servico .servico-fecho{opacity:1;transform:none}
}

/* ---- CADA ÍCONE FAZ O QUE A COISA FAZ ----------------------------------------------
   Enquanto está grande, o ícone não fica parado: faz o gesto do serviço que nomeia, e
   acaba exatamente no desenho de sempre no instante em que assenta no canto. Nenhuma
   destas animações é um efeito aplicado por fora — cada uma é o que aquele objeto faz.
   É isso que as faz ler-se como significado e não como enfeite.

   Quatro números escritos pelo `entrada-cartoes.js` em cada cartão dão-lhes o movimento, e
   TODOS morrem em repouso por construção — a rotação acaba num número inteiro de voltas,
   o que oscila é multiplicado por uma energia que chega a zero, e o que se desenha acaba
   com o traço inteiro. Um ícone parado numa posição que não é a dele lê-se como avariado,
   e é isso que uma animação CSS em `infinite` não sabe evitar:
     --q       0 -> 1, o andamento (acaba quando o ícone assenta)
     --onda    vaivém que se esgota (seno x energia), acaba em zero
     --balanco o mesmo, desencontrado, para varrer em oval
     --vida    a energia que resta (1 -> 0): é ela que apaga o que oscila

   Os seletores estão todos presos a `.servico`: as partes existem no sprite, que a
   homepage também usa, e lá não devem fazer nada. */
.servico{--q:1;--onda:0;--balanco:0;--vida:0}

/* Auditorias — a lupa INSPECIONA: por dentro da lente desfila uma tira de coisas
   medidas, recortada pelo aro. O vidro varre pouco, de propósito: quem faz o trabalho é
   o que passa lá dentro. A tira corre a passo CERTO (presa ao `--q`, que é linear) e não
   com a travagem dos outros — uma inspeção que abranda a meio lê-se como avaria; quem a
   acaba é o desvanecimento no fim, e por isso em repouso a lente fica limpa.
   ARMADILHA: o `clip-path` é aplicado DEPOIS da transformação do próprio elemento, por
   isso o recorte vive num grupo QUIETO e é o filho dele que anda. */
.servico .p-busca{transform-box:view-box;transform-origin:12px 12px;
  transform:translate(calc(var(--onda) * 1.7px), calc(var(--balanco) * .8px))}
.servico .p-desfile{transform-box:view-box;stroke-width:1.25;
  opacity:clamp(0, (1 - var(--q)) * 8, 1);
  transform:translateX(calc(var(--q) * -56px))}

/* AVAC — o floco CRISTALIZA: os seis braços crescem do centro para fora, todos ao mesmo
   tempo, e as pontas ramificam quando eles já lá estão. Rodava, e o cliente apanhou que
   não dizia nada: um floco de neve não roda, FORMA-SE. É a mesma regra das outras doze —
   a animação é o que aquele objeto faz, não um efeito posto por cima.
   Os braços são SEIS caminhos e não um: num `path` com vários subcaminhos o tracejado
   continua de um para o outro, e eles desenhavam-se em fila em vez de crescerem juntos. */
.servico .p-braco{stroke-dashoffset:calc((1 - clamp(0, var(--q) / .7, 1)) * var(--len))}
.servico .p-pontas{opacity:clamp(0, (var(--q) - .58) * 3.6, 1)}

/* SVG PRÓPRIO (colado pelo cliente no backoffice, 2026-09-29) — DESENHA-SE traço a traço:
   o `entrada-cartoes.js` dá a classe a cada forma e escreve `--i` (o índice) e `--n` (o
   total). As formas desenham-se em sequência, com sobreposição: a `i` arranca quando o
   andamento passa `i/(n+1)` e demora `2/(n+1)`. Com `--q:1` em repouso o offset é 0 (o
   ícone inteiro); com `--q:0`, na partida, é `--len` (invisível). É a mesma fórmula do
   `.p-sobe`, generalizada. Os ícones da biblioteca nunca a apanham: têm partes nomeadas. */
.servico .p-desenha{stroke-dashoffset:calc((1 - clamp(0, (var(--q) * (var(--n) + 1) - var(--i)) / 2, 1)) * var(--len))}

/* Térmicos — o mercúrio SOBE do bolbo, e as marcas da escala acendem quando ele passa. */
.servico .p-sobe{stroke-dashoffset:calc((1 - var(--q)) * var(--len))}
.servico .p-tique{opacity:clamp(0, (var(--q) - .34) * 5, 1)}
.servico .p-tique-alto{opacity:clamp(0, (var(--q) - .52) * 5, 1)}

/* Certificação — o visto DESENHA-SE na folha. */
.servico .p-visto{stroke-dashoffset:calc((1 - clamp(0, (var(--q) - .18) / .82, 1)) * var(--len))}

/* GTC — o traço CORRE pelo ecrã, como um monitor a varrer, e assenta contínuo: o vão do
   tracejado encolhe com a energia e, a zero, a linha fica inteira.

   A passo CERTO (preso ao `--q`, que é linear) e não com a travagem dos outros — é a
   mesma escolha da tira da lupa e dos raios do painel, e pela mesma razão: um varrimento
   que abranda a meio não é um varrimento. Estava travado e o cliente apanhou-o ("está
   muito rápido"): com a travagem, 60% do percurso acontecia no primeiro QUARTO do tempo,
   e o que se via era um borrão seguido de quase nada. O percurso também encurtou, de 46
   para 18 unidades — a três padrões de tracejado, que é o que se lê como uma passagem em
   vez de uma corrida. */
.servico .p-traco{stroke-dasharray:3.4px calc(var(--vida) * 3.4px);
  stroke-dashoffset:calc(var(--q) * -18px)}

/* Gestão de energia — a linha SOBE e a seta CHEGA ao fim dela. */
.servico .p-linha{stroke-dashoffset:calc((1 - var(--q)) * var(--len))}
.servico .p-ponta{transform-box:view-box;transform-origin:20px 7.6px;
  opacity:clamp(0, (var(--q) - .74) * 5, 1);
  transform:scale(clamp(.3, (var(--q) - .74) * 5, 1))}

/* Manutenção — a chave APERTA: roda e volta, e assenta direita. */
.servico .p-aperta{transform-box:view-box;transform-origin:12px 12px;
  transform:rotate(calc(var(--onda) * 16deg))}

/* Smart Rooms — o SINAL liga-se, arco a arco, de dentro para fora. */
.servico .p-sinal-perto{stroke-dashoffset:calc((1 - clamp(0, (var(--q) - .15) / .3, 1)) * var(--len))}
.servico .p-sinal-longe{stroke-dashoffset:calc((1 - clamp(0, (var(--q) - .4) / .35, 1)) * var(--len))}

/* Contratos — o contrato FAZ-SE pela ordem por que se faz: as cláusulas, a assinatura, e
   o traço que a fecha por baixo. As cláusulas vão num traço mais fino do que a folha,
   para se lerem como texto e não como estrutura. */
.servico .p-clausula{stroke-width:1.3;
  stroke-dashoffset:calc((1 - clamp(0, var(--q) / .42, 1)) * var(--len))}
.servico .p-assina{stroke-dashoffset:calc((1 - clamp(0, (var(--q) - .34) / .52, 1)) * var(--len))}
.servico .p-risco{stroke-dashoffset:calc((1 - clamp(0, (var(--q) - .8) / .2, 1)) * var(--len))}

/* Fotovoltaico — caem RAIOS DE SOL sobre o painel, e ele procura o sol como um seguidor.
   Os quatro raios estão no mesmo `path`, e é isso que os desencontra: o tracejado
   continua de um subcaminho para o outro, por isso cada um arranca numa fase diferente.
   Vão a 45 graus e quase contínuos — ao quase-vertical e picados liam-se como CHUVA. */
.servico .p-raios{stroke-width:1.25;stroke-dasharray:5.4px 2.1px;
  stroke-dashoffset:calc(var(--q) * -34px);
  opacity:clamp(0, (1 - var(--q)) * 5, 1)}
.servico .p-inclina{transform-box:view-box;transform-origin:12px 17.8px;
  transform:rotate(calc(var(--onda) * 7deg))}

/* 3D Scan — o modelo MONTA-SE, aresta a aresta. As arestas estão todas no mesmo `path`,
   por isso um só tracejado as desenha em sequência: é a leitura certa para um
   levantamento que se vai reconstruindo. */
.servico .p-monta{stroke-dashoffset:calc((1 - var(--q)) * var(--len))}

/* AQS — o VAPOR ondula sobre a gota. Cada fio com a sua amplitude e um deles ao
   contrário: é isso que os faz parecer três e não um repetido três vezes. */
.servico .p-vapor{transform-box:view-box}
.servico .p-vapor-1{transform:translateY(calc(var(--onda) * -1.6px))}
.servico .p-vapor-2{transform:translateY(calc(var(--onda) * 1.2px))}
.servico .p-vapor-3{transform:translateY(calc(var(--onda) * -1px))}

/* Fundos — o € é ESCRITO no impresso, e as linhas por baixo a seguir. */
.servico .p-euro{stroke-dashoffset:calc((1 - clamp(0, var(--q) / .6, 1)) * var(--len))}
.servico .p-barras{stroke-dashoffset:calc((1 - clamp(0, (var(--q) - .55) / .45, 1)) * var(--len))}

/* ---------------------------------------------------------------- o fecho
   As regras do `.chamada` (o convite ao contacto que fecha a página) passaram para o
   `base.css` a 2026-09-28, quando a página Sobre passou a usar o mesmo bloco — duas cópias
   do mesmo desenho divergem, como os `.btn` em setembro. */

/* ---------------------------------------------------------------- ecrãs estreitos */
@media (max-width:820px){
  /* A uma coluna o 2x2 não existe, e o cartão passa a valer o que o texto pedir: com a
     altura de meio ecrã imposta, treze cartões davam uma página interminável. */
  .servicos-grelha{grid-template-columns:1fr}
  .servico{min-height:0}
  .servico:last-child:nth-child(odd){grid-column:auto}
  .servico:last-child:nth-child(odd) p{max-width:52ch}
}

@media (max-width:560px){
  /* Num telemóvel o título quebra em duas linhas quase tão largas como o ecrã: a mancha
     fica baixa e larga, e a elipse acompanha-a — mais aberta de lado e mais fechada de
     alto do que a do computador, senão sobrava véu por cima e por baixo das letras e a
     malha desaparecia do pouco espaço que ali tem. */
  /* No telemóvel o hero da inicial desce a `clamp(21px,6.8vw,30px)` porque é uma FRASE
     de duas linhas ao lado de nada; aqui é UMA palavra sozinha num ecrã, e a 26px lia-se
     como um título de secção e não como a capa de uma página. É a única diferença
     deliberada entre os dois. */
  .capa-titulo{font-size:clamp(34px,9vw,44px)}
  /* No telemóvel a mancha do título é baixa e quase tão larga como o ecrã, e o sinal
     ocupa a largura toda: os dois clarões abrem de lado e o pescoço quase desaparece. */
  .capa-veu{background:
    radial-gradient(ellipse 54% 20% at 50% 46%,
      #fff 0%,#fff 56%,rgba(255,255,255,.88) 78%,rgba(255,255,255,0) 100%),
    radial-gradient(ellipse 46% 26% at 50% 86%,
      #fff 0%,#fff 52%,rgba(255,255,255,.85) 76%,rgba(255,255,255,0) 100%)}
}
