/* =============================================================================
   TOOSAFE - Sistema de desenho "Pauta de Luz"
   -----------------------------------------------------------------------------
   A ideia: do logótipo TOOSAFE, o elemento abstraível não é a letra - é a BARRA
   sólida com gradiente por baixo do lettering. Essa barra é libertada do logótipo
   e torna-se o sistema estrutural de todo o site. A página é uma folha de papel
   quente atravessada por réguas de 1px (a "pauta"), e a barra azul é a única
   tinta saturada que existe.

   Regras que este ficheiro nunca quebra:
     1. Só se anima transform, opacity e (pontualmente) filter. Nunca width,
        height, box-shadow, top/left - essas obrigam o browser a recalcular
        a página em cada fotograma e destroem a fluidez no telemóvel.
     2. Nenhum box-shadow. Onde é preciso profundidade, usa-se um gradiente
        já pintado num pseudo-elemento.
     3. Nenhum atraso de animação vem do HTML. A política de segurança do site
        proíbe style="..." em linha, por isso os desfasamentos são regras
        :nth-child() escritas aqui.
     4. Nunca se anima font-variation-settings - obriga a remedir o texto em
        cada fotograma.
     5. Zero pedidos a servidores externos. Tudo é servido do próprio domínio.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   1. TIPO DE LETRA
   Archivo Variable (licença SIL Open Font, alojada no vosso servidor).
   Um único desenho serve todo o site porque tem dois eixos: peso (100-900) e
   largura (62-125%).

   SÃO DOIS FICHEIROS, e isso é essencial. O Google divide a fonte por
   intervalos de caracteres: o "latin" traz as letras normais e as acentuadas
   do português (U+0000-00FF), o "latin-ext" traz o resto do alfabeto latino.
   Ter só o segundo era o mesmo que não ter fonte nenhuma para A-Z: essas
   letras caíam para a letra do sistema e ficavam com outro peso, misturadas
   no meio das acentuadas. Era daí que vinham as letras que pareciam bold.
-------------------------------------------------------------------------------*/
@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* -----------------------------------------------------------------------------
   2. TOKENS
   Alterar uma cor aqui altera-a em todo o site. Não escrever cores soltas
   no resto do ficheiro.
-------------------------------------------------------------------------------*/
:root {
  /* --- Superfícies ------------------------------------------------------- */
  --paper:        #F8F7F4;  /* tela da página: branco quente, papel e não ecrã */
  --sheet:        #FFFFFF;  /* superfície elevada: rodapé, fichas de contacto  */

  /* --- Texto -------------------------------------------------------------
     Os três níveis foram verificados contra --paper. Nenhum desce abaixo
     do mínimo legal de 4.5:1 exigido pelas normas de acessibilidade.        */
  --ink:          #12151A;  /* primário - 16.8:1  */
  --ink-2:        #5B636E;  /* secundário - 5.7:1  */
  --ink-3:        #676E7A;  /* terciário - 4.8:1  */

  /* --- Réguas: a "pauta" que dá nome ao conceito ------------------------- */
  --rule:         #E2E0DA;
  --rule-strong:  #C9C6BE;

  /* --- Azul da marca, amostrado do logótipo ------------------------------ */
  --blue-deep:    #0173BE;  /* início exato do gradiente do logótipo */
  --blue-bright:  #26A8E0;  /* fim exato do gradiente do logótipo    */
  --blue-ink:     #0A5C9E;  /* azul legível como texto - 6.6:1       */
  --blue-wash:    #EAF4FB;  /* único preenchimento azul permitido    */
  --grad:         linear-gradient(90deg, var(--blue-deep) 0%, var(--blue-bright) 100%);

  /* A cor de junção do tema escuro. Era var(--noite) - preto com um sopro de azul -
     e lia-se mesmo como preto entre uma empresa e a seguinte. Passa a ser um
     azul-noite com corpo. TODAS as junções usam esta cor: o fim do vídeo do
     topo, as duas pontas de cada empresa, o corpo da página e o rodapé. É o que
     faz o site correr de uma ponta à outra sem nenhum troço morto. */
  --noite:        #08101A;

  /* --- Curvas de movimento -----------------------------------------------
     --e-out  : entra depressa e assenta devagar. Para coisas que aparecem.
     --e-move : simétrica e calma. Para coisas que se deslocam.
     --e-press: resposta imediata ao toque.                                  */
  --e-out:        cubic-bezier(.16, 1, .3, 1);
  --e-move:       cubic-bezier(.33, 1, .68, 1);
  --e-press:      cubic-bezier(.2, 0, 0, 1);

  /* --- Ritmo -------------------------------------------------------------- */
  --gutter:       clamp(20px, 5vw, 64px);
  --max:          1320px;
  --stagger:      90ms;   /* desfasamento entre elementos irmãos a revelar */

  /* --- Escala tipográfica -------------------------------------------------
     Tudo em clamp(): cresce com o ecrã sem saltos bruscos entre tamanhos.   */
  --step--1:      clamp(.8125rem, .78rem + .17vw, .875rem);    /* 13 → 14 */
  --step-0:       clamp(1rem, .96rem + .2vw, 1.0625rem);       /* 16 → 17 */
  --step-1:       clamp(1.125rem, 1.05rem + .37vw, 1.375rem);  /* 18 → 22 */
  --step-2:       clamp(1.5rem, 1.3rem + 1vw, 2.25rem);        /* 24 → 36 */
  --step-3:       clamp(2rem, 1.5rem + 2.5vw, 3.5rem);         /* 32 → 56 */
  /* Descido a 6 out 2026. A 47px, "Uma estrutura comum." precisava de 438px e
     só havia 335 num telemóvel: partia e deixava o "comum." sozinho na quarta
     linha. A 36px as três frases do lema cabem cada uma na sua linha, que é
     como foram escritas. O cliente aceitou expressamente o corpo mais pequeno
     em troca de ficar bem formatado. */
  --display:      clamp(2rem, .82rem + 5.57vw, 7.5rem);         /* 34 → 120 */
  --micro:        .75rem;    /* 12px - constante do sistema, nunca escala */

  --font: "Archivo", system-ui, -apple-system, "Segoe UI Variable Text",
          "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* --- O FUNDO, definido UMA vez ---------------------------------------
     Esta variável é usada pelo corpo da página E pelo cabeçalho. Como
     ambos a pintam com background-attachment: fixed, o gradiente fica preso
     ao ecrã e não à caixa de cada um. O resultado é que o pedaço de
     gradiente que o cabeçalho mostra é exatamente o mesmo que estaria ali
     se o cabeçalho não existisse.

     É por isso que não se vê a fronteira: não há duas superfícies a
     encontrar-se, há uma só, pintada duas vezes no mesmo sítio. E mantém-se
     verdadeiro a qualquer altura de scroll, porque nenhuma das duas se move.  */
  /* --- A SUPERFÍCIE DOS BLOCOS ------------------------------------------
     Os painéis das empresas são feitos destes três tons. Ficam aqui como
     variáveis porque têm de acompanhar o fundo: um painel branco sobre papel
     creme flutua e denuncia-se, tal como um painel creme sobre fundo azul.
     Trocar de fundo obriga a trocar também estes três valores, e é por isso
     que vivem no mesmo sítio. */
  --painel-1: rgba(255, 255, 255, .52);
  --painel-2: rgba(255, 255, 255, .26);
  --painel-3: rgba(255, 255, 255, .10);
  --painel-borda: rgba(255, 255, 255, .58);

  /* --- OS BOTÕES ---------------------------------------------------------
     O preenchimento dos botões estava escrito à mão dentro da regra, e por
     isso continuava claro mesmo quando o fundo do site passava a escuro:
     ficava texto apagado sobre uma superfície clara num site escuro.
     Passa a variável, e cada fundo escuro redefine-a. */
  --acao-fundo-1:    #FDFDFB;
  --acao-fundo-2:    #F7F8F8;
  --acao-fundo-hover: #FFFFFF;
  --acao-fundo-press-1: #F2F6F9;
  --acao-fundo-press-2: #E9F1F7;

  /* Chapa por trás do logótipo da empresa. Invisível nos fundos claros.
     Nos escuros ganha corpo, senão um logótipo azul-escuro como o da
     Detalhe Compatível desaparece por completo. */
  --logo-chapa: transparent;
  --logo-chapa-pad: 0px;

  --fundo-cor: #F5F5F2;
  --fundo: linear-gradient(
    176deg,
    #FDFCFA   0%,
    #FBFAF7   9%,
    #F9F8F5  18%,
    #F7F7F4  27%,
    #F5F5F3  36%,
    #F3F4F3  45%,
    #F1F3F3  54%,
    #EFF2F4  63%,
    #EDF1F4  72%,
    #EBF0F4  81%,
    #E9EFF4  90%,
    #E7EEF5 100%
  );
}

/* -----------------------------------------------------------------------------
   3. REPOSIÇÃO
-------------------------------------------------------------------------------*/
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Compensa a barra de navegação fixa quando se salta para uma âncora. */
  scroll-padding-top: 96px;
}

/* O FUNDO - uma só superfície contínua, do topo ao rodapé.
   -----------------------------------------------------------------------
   Regra absoluta deste site: NENHUMA secção tem fundo próprio. Se o rodapé
   fosse branco e o corpo cinzento, via-se a fronteira entre os dois - e é
   exatamente essa fronteira que faz uma página parecer feita de blocos
   empilhados em vez de uma superfície inteira.

   Duas decisões que garantem que nunca se vê uma paragem:

   1. MUITOS PASSOS DE COR. Um gradiente com 3 ou 4 passos cria "bandas" - degraus visíveis onde a cor salta. Com 12 passos muito próximos, a
      transição é mais fina do que o olho distingue.

   2. FIXO AO ECRÃ. O gradiente não acompanha o scroll. Não havendo
      movimento relativo entre o fundo e o conteúdo, não pode existir uma
      costura, por mais que se role a página.

   O grão de papel por cima ajuda ainda mais: o ruído quebra as bandas que
   pudessem sobrar. É a mesma técnica usada na impressão a cores. */
body {
  margin: 0;
  background-color: var(--fundo-cor);
  background-image: var(--fundo);
  background-attachment: fixed;
  background-repeat: no-repeat;
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--step-0);
  font-weight: 350;
  line-height: 1.6;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

h1, h2, h3, p, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg, video { display: block; max-width: 100%; }
a { color: inherit; }
button { font: inherit; color: inherit; }

/* O anel de foco é a única forma de quem navega por teclado saber onde está.
   Nunca remover. */
:focus-visible {
  outline: 2px solid var(--blue-deep);
  outline-offset: 3px;
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }

/* Salto para o conteúdo - invisível até receber foco pelo teclado. */
.saltar {
  position: absolute;
  left: var(--gutter);
  top: 0;
  z-index: 100;
  padding: 12px 20px;
  background: var(--ink);
  color: var(--paper);
  text-decoration: none;
  font-size: var(--micro);
  letter-spacing: .12em;
  text-transform: uppercase;
  transform: translateY(-120%);
  transition: transform 220ms var(--e-out);
}
.saltar:focus { transform: translateY(0); }

/* Só para leitores de ecrã. */
.sr {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* -----------------------------------------------------------------------------
   4. VOZES TIPOGRÁFICAS
   Três vozes, um só tipo de letra. Usa-se font-weight e font-stretch (e nunca
   font-variation-settings) porque assim os eixos também funcionam quando o
   site cai para a letra do sistema.
-------------------------------------------------------------------------------*/

/* Voz de titular: finíssima e grande. */
.display {
  font-size: var(--display);
  font-weight: 220;
  font-stretch: 100%;
  line-height: .94;
  letter-spacing: -.022em;
  text-wrap: balance;
}

/* Voz editorial: maiúsculas pequenas para o número de índice e o setor.
   Deliberadamente MODERADA - 12px e espaçamento de .05em. Maiúsculas
   minúsculas com espaçamento muito aberto são a marca de água dos modelos
   pré-feitos, e lêem-se logo como tal. Aqui a letra é grande o suficiente
   para se ler de relance e apertada o suficiente para parecer escrita por
   alguém. */
/* NADA de maiúsculas com espaçamento aberto. Era o que restava do aspeto
   "modelo pré-feito" e é a primeira coisa que denuncia um site que não foi
   desenhado por ninguém. As etiquetas pequenas passam a ser simplesmente
   texto pequeno: mesma família, mesma caixa, só mais discreto. */
.label {
  font-size: .8125rem;
  font-weight: 460;
  font-stretch: 100%;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  line-height: 1.35;
}
.label--ink { color: var(--ink); }

/* Compensação óptica: em ecrãs pequenos, letra finíssima "lava-se" - sobretudo
   em painéis Android de baixa densidade e à luz do sol. Por isso o peso sobe. */
@media (max-width: 400px) {
  .display { font-weight: 280; font-stretch: 96%; }
}
/* Piso absoluto: nada abaixo de 24px desce de peso 350. */
.texto, p { font-weight: 350; }

/* -----------------------------------------------------------------------------
   5. ESTRUTURA
   As réguas são full-bleed (de margem a margem do ecrã) enquanto o conteúdo
   respeita a goteira. É isso que impede o site de parecer uma app de cartões
   e mantém a identidade de folha impressa.
-------------------------------------------------------------------------------*/
.envelope {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.regua {
  height: 1px;
  background: var(--rule);
  transform: scaleX(0);
  transform-origin: 0 50%;
}
.regua--forte { background: var(--rule-strong); }

/* -----------------------------------------------------------------------------
   6. CAMADA DE LUZ AMBIENTE
   Uma única camada fixa com um gradiente radial muito ténue que deriva
   lentamente. A suavidade vem da própria queda do gradiente e não de um
   filtro de desfoque - desfocar uma superfície grande é das operações mais
   caras que existem num telemóvel.
   A camada é limitada a 130% do ecrã: uma camada gigante seria uma textura
   de dezenas de megabytes permanentemente na memória gráfica.
-------------------------------------------------------------------------------*/
.luz {
  position: fixed;
  top: -15vh;
  left: -15vw;
  width: 130vw;
  height: 130vh;
  z-index: 0;
  pointer-events: none;
  contain: strict;
  background:
    radial-gradient(42% 34% at 26% 32%, rgba(38, 168, 224, .22), rgba(38, 168, 224, 0) 68%),
    radial-gradient(38% 30% at 78% 62%, rgba(1, 115, 190, .16), rgba(1, 115, 190, 0) 70%),
    radial-gradient(30% 24% at 52% 88%, rgba(38, 168, 224, .12), rgba(38, 168, 224, 0) 72%);
  animation: deriva 38s linear infinite;
  will-change: transform;
}

/* Camada 3: grão de papel.
   Uma textura de ruído gerada pelo próprio browser - cerca de 300 bytes de
   código, sem qualquer imagem a descarregar. É pintada uma única vez e nunca
   se move, por isso não custa nada. É o que tira o aspeto "ecrã" e dá o
   aspeto "impresso": a diferença entre um fundo liso e uma superfície. */
.grao {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .05;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
  contain: strict;
}
@keyframes deriva {
  0%   { transform: translate3d(-5vw,  2vh, 0); }
  50%  { transform: translate3d( 6vw, -3vh, 0); }
  100% { transform: translate3d(-5vw,  2vh, 0); }
}
/* Quando o separador deixa de estar à vista, a animação pára de consumir
   bateria. A classe é posta pelo JavaScript. */
.pausado .luz { animation-play-state: paused; }

/* -----------------------------------------------------------------------------
   Camada 2b: a FOTOGRAFIA DE FUNDO.
   Só existe nas páginas Sobre e Contactos. A entrada não leva nenhuma: lá o
   fundo são os vídeos, e duas coisas a disputar o mesmo lugar seria ruído.

   Fica ENTRE o gradiente do corpo e o brilho azul, por isso é escrita antes
   da camada .luz no HTML - as duas têm z-index 0 e é a ordem no documento que
   decide qual pinta por cima. De baixo para cima: gradiente, fotografia,
   brilho azul, grão, conteúdo. A fotografia nunca toca no conteúdo nem no
   cabeçalho, que vivem acima (.pagina tem z-index 1 e o cabeçalho 50).

   A OPACIDADE É O NÚMERO QUE IMPORTA, e está calculada, não escolhida a olho.
   O sítio mais claro das duas fotografias é a luva branca (#D8DCE0). A 30%
   sobre o fundo, esse ponto sobe a #4D5154, e é só ali:
     --ink   (títulos)        7.3:1
     --ink-2 (texto corrido)  5.1:1
     --ink-3 (etiquetas)      4.5:1
   Nenhum desce do mínimo legal de 4.5:1 nem no pior ponto da página - e esse
   ponto está por baixo da máscara, portanto na prática nem chega aos 30%.
   Para a fotografia ficar mais forte ou mais fraca, mexe-se só em --foto-op.

   A MÁSCARA tem UMA só rampa, e isto foi a correcção de 7 out 2026. Antes
   fechava outra vez em baixo, e isso era um erro: a camada está presa ao ecrã,
   portanto esse fecho não ficava no fim da PÁGINA - ficava no fim do ECRÃ,
   sempre no mesmo sítio, e lia-se como um corte horizontal a meio do que se
   estava a ver. Agora entra uma vez no topo, onde o cabeçalho passa por cima,
   e daí para baixo fica igual até ao fim. Não há nenhuma aresta onde a
   fotografia comece ou acabe: ela é o chão da página inteira.
-------------------------------------------------------------------------------*/
.foto {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  contain: layout paint;
}

.foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: var(--foto-op, .22);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 34%, #000 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 34%, #000 100%);
}

/* --- ALTERNATIVA: O DEGRADÉ DAS EMPRESAS EM VEZ DA FOTOGRAFIA --------------
   A mesma camada, sem <img> lá dentro e com o gradiente das secções das
   empresas pintado directamente. Serve para comparar os dois tratamentos, e
   troca-se num sítio só: "fundoPaginas" em dados\site.json.

   O gradiente é COPIADO de .empresa__media, não aproximado. Tem de ser o
   mesmo, senão a comparação não vale nada - e fora de um bloco de empresa as
   variáveis --marca-1 e --marca-2 não existem, portanto entram os valores de
   reserva, que são justamente os azuis da TooSafe. É o mesmo chão que dá o
   seguimento entre empresas na entrada.

   Na entrada este gradiente é pintado por BLOCO, de 84svh cada, e por isso
   respira enquanto se desliza - escurece, abre, volta a escurecer. Aqui é uma
   camada presa ao ecrã e desenha o ciclo uma só vez, portanto ficava parada.
   É daí que vem a deriva lá em baixo: devolve o movimento que o scroll dava.

   Está partido em DUAS camadas, e não é arrumação:
     - a base escura fica no próprio elemento, quieta. É ela que dá a estrutura
       da página e não pode mexer-se, senão a página inteira pulsa de brilho.
     - o azul vai para um ::after maior que o ecrã, que deriva devagar.
   É a mesma divisão que o site já faz na entrada entre o fundo do corpo (que
   está quieto) e a camada .luz (que anda). */
.foto--degrade {
  background: linear-gradient(to bottom,
    var(--noite) 0%,
    #0C1622 42%,
    #0B1420 62%,
    var(--noite) 100%);
}

/* O AZUL, mais fraco e a mexer.
   As quatro manchas são as mesmas da entrada, aos mesmos sítios e com as
   mesmas forças. O que muda é terem um --degrade-azul por cima a cortá-las a
   pouco mais de metade, e a razão é concreta: na entrada este azul está por
   baixo do vídeo, que o abafa; aqui não tem nada por cima e lê-se ao dobro.
   Para o subir ou baixar mexe-se SÓ nesse número.

   Maior que o ecrã (os -18%) para poder andar sem nunca deixar ver uma borda.

   DUAS camadas e não uma, e a razão é a correcção de 7 out: a primeira versão
   só deslizava, e deslizar NÃO SE VÊ num gradiente suave. Uma mancha de 300px
   arrastada 25px muda a cor de cada ponto por uma fracção de nada - a animação
   corria, e com razão ninguém dava por ela.

   O que se vê num gradiente é a INTENSIDADE a mudar. Por isso as manchas de
   cima e as de baixo estão separadas e andam em contrafase: quando o azul do
   canto de cima acende, o de baixo apaga, e ao fim de meio ciclo trocam. A luz
   atravessa a página em vez de se arrastar. O deslize e o leve crescimento
   continuam lá por baixo disso, a tirar-lhe a regularidade.

   DOIS BOTÕES, e são estes:
     --degrade-azul   quanta cor tem      (0 apaga, .55 é o afinado por ele)
     --degrade-ritmo  quão depressa anda  (menor = mais rápido)
   A segunda camada anda sempre a 1,3x do tempo da primeira, de propósito:
   períodos diferentes nunca voltam a cruzar-se no mesmo ponto, e o padrão
   não se deixa decorar.

   O RITMO ESTÁ ONDE ESTÁ POR CONTA FEITA, não por gosto. A 44 segundos, o
   canal azul variava 8 níveis em 255 ao longo de 22 segundos - 0,14% por
   segundo, que é abaixo do que o olho deteta num campo de pouco contraste.
   Media-se, não se via. A 20 segundos e com a amplitude aberta, passa a
   mexer-se cerca de 1,4 níveis por segundo, que já se nota. Se vier a parecer
   um efeito em vez de fundo, sobe-se o --degrade-ritmo e volta a assentar.

   Continua a não repintar nada. Transform e opacidade são as duas únicas
   coisas que um browser resolve sem voltar a desenhar a página, e são as duas
   únicas que aqui se mexem. */
.foto--degrade::before,
.foto--degrade::after {
  content: "";
  position: absolute;
  inset: -18%;
  pointer-events: none;
  opacity: var(--degrade-azul, .55);
  will-change: transform, opacity;
}

/* As manchas do canto de cima, à direita. */
.foto--degrade::before {
  background:
    radial-gradient(90% 80% at 76% 26%, rgba(1, 115, 190, .16), transparent 70%),
    radial-gradient(92% 82% at 74% 28%, rgba(1, 115, 190, .26), transparent 72%);
  animation: deriva-cima var(--degrade-ritmo, 20s) ease-in-out infinite;
}

/* As do canto de baixo, à esquerda. */
.foto--degrade::after {
  background:
    radial-gradient(76% 74% at 22% 84%, rgba(38, 168, 224, .14), transparent 74%),
    radial-gradient(80% 76% at 20% 86%, rgba(38, 168, 224, .10), transparent 76%);
  animation: deriva-baixo calc(var(--degrade-ritmo, 20s) * 1.3) ease-in-out infinite;
}

/* Os passos de 7 e 8% são o máximo que cabe nos 18% de folga, já com o
   crescimento de 1,07 contado. Nunca pode aparecer uma borda. */
@keyframes deriva-cima {
  0%, 100% { transform: translate3d(-7%,  5%, 0) scale(1);
             opacity: calc(var(--degrade-azul, .55) * .62); }
  50%      { transform: translate3d( 8%, -6%, 0) scale(1.1);
             opacity: calc(var(--degrade-azul, .55) * 1.34); }
}

@keyframes deriva-baixo {
  0%, 100% { transform: translate3d( 6%, -5%, 0) scale(1.1);
             opacity: calc(var(--degrade-azul, .55) * 1.34); }
  50%      { transform: translate3d(-7%,  6%, 0) scale(1);
             opacity: calc(var(--degrade-azul, .55) * .62); }
}

/* Quem pediu menos movimento pediu menos movimento. As duas camadas ficam,
   quietas e à força normal - o fundo não perde nada, só pára. */
@media (prefers-reduced-motion: reduce) {
  .foto--degrade::before,
  .foto--degrade::after { animation: none; transform: none; }
}

/* O RODAPÉ DEIXA DE PINTAR FUNDO nas páginas que levam fotografia.
   Era isto que a cortava: em tema escuro o rodapé pinta var(--noite) chapado,
   e como o conteúdo vive acima da camada da fotografia (z-index 1 contra 0),
   essa cor tapava-a a direito. Dava um risco horizontal exactamente onde o
   rodapé começa - o corte que se via por cima das bandeiras.

   Na ENTRADA esse fundo opaco continua a ser preciso, e por isso a regra é
   travada com :has(.foto): lá o rodapé vem a seguir à última empresa e tem de
   ser a mesma cor para a junção não se notar. Aqui não há empresa nenhuma por
   cima - há a fotografia, que tem de passar por baixo do rodapé e seguir até
   ao fim do ecrã. */
:root[data-tema="escuro"]:has(.foto) .rodape { background: transparent; }

/* O GRÃO VOLTA, só nestas duas páginas. Está desligado no tema escuro porque
   sujava as cores próprias dos blocos das empresas - mas aqui não há blocos,
   há uma fotografia escura com grandes zonas de degradé suave, e é
   precisamente aí que o webp faz bandas. O ruído quebra-as. É também o que
   junta a fotografia ao fundo: as duas passam a ter a mesma textura por cima,
   portanto lêem-se como uma superfície só e não como uma imagem colada.
   A .028 não se vê como grão; vê-se como a ausência das bandas. */
:root[data-tema="escuro"]:has(.foto) .grao {
  display: block;
  opacity: .028;
}

/* ENQUADRAMENTO. As duas fotografias são quadradas e o ecrã do telemóvel é
   alto e estreito, por isso vê-se a altura toda e só uns 46% da largura. O que
   se escolhe aqui é QUAL 46% - e o critério não é estético, é de leitura: o
   ponto mais claro de cada fotografia tem de ficar FORA da coluna do texto.
   Ao centro, as duas punham a parte branca - a luva numa, a mão na outra -
   exactamente por trás dos títulos. Puxadas para a esquerda, a metade clara
   sai do recorte e o que fica é o lado escuro e geométrico, que é o que
   interessa a um fundo. */
.foto--sobre img     { object-position: 30% 50%; }
.foto--contactos img { object-position: 40% 50%; }

/* A FOTOGRAFIA DOS CONTACTOS DESCE, para os símbolos dela encontrarem os
   campos certos: o telefone ao lado do telefone, o envelope ao lado do email.
   Estava tudo desencontrado uma linha - o telefone ficava à frente do
   parágrafo de abertura e o envelope à frente do número.

   Os 14svh não são um palpite. Medidos no telemóvel de 375x812:
     símbolos na imagem   33,0%  46,6%  58,0% da altura
     ou seja, no ecrã       268    378    471
     campos a alinhar       381    488    602  (centro de cada valor)
   A diferença é de 113px, que são 13,9% da altura do ecrã. Com a descida, o
   telefone cai em 381 (certo ao pixel) e o envelope em 491 contra 488 - três
   pixels. O balão de conversa fica em 584 contra os 602 da morada, 18 fora,
   e isso não se corrige: o espaçamento entre os símbolos da fotografia é o
   que é, e só se alinham dois com exactidão. Alinhei os dois que ele nomeou.

   Em svh e não em px porque as folgas da página são em vh: se o ecrã for mais
   alto, os campos descem e a fotografia desce com eles.

   NÃO FICA ARESTA no sítio onde a imagem passa a começar. A máscara está
   aplicada à IMAGEM, não ao ecrã, por isso desce com ela: a fotografia entra
   a zero exactamente na sua própria borda de cima, onde quer que ela caia. */
.foto--contactos img {
  position: relative;
  top: 14svh;
}

/* Todo o conteúdo vive acima da camada de luz. */
.pagina { position: relative; z-index: 1; }

/* -----------------------------------------------------------------------------
   7. CABEÇALHO E NAVEGAÇÃO
   Sem hambúrguer. As quatro páginas cabem numa linha de maiúsculas
   condensadas a 11px, por isso o menu está sempre visível - que é a decisão
   mais amiga do utilizador num site cujo objetivo é dar acesso depressa.
-------------------------------------------------------------------------------*/
/* O cabeçalho também não é um bloco: o fundo desvanece-se para transparente
   na aresta de baixo, por isso o conteúdo passa por trás sem nunca cruzar uma
   linha dura. A única aresta visível é a barra da marca, que é intencional. */
/* O cabeçalho pinta EXATAMENTE o mesmo fundo fixo do corpo da página. Não é
   uma cor parecida nem um vidro fosco: é o mesmo gradiente, preso ao mesmo
   ecrã. Por isso não existe fronteira nenhuma para se notar, e o conteúdo
   passa por baixo sem nunca atravessar uma aresta. */
/* --- O CABEÇALHO DENTRO DA IMAGEM -----------------------------------------
   Deixa de ser uma barra sólida pousada por cima da página e passa a fazer
   parte dela: fundo transparente, logótipo e navegação a branco, com um
   escurecimento muito suave no topo para se lerem sobre qualquer vídeo.

   Não há aqui nenhuma linha, nenhuma aresta e nenhum bloco - que era
   exatamente o que estava a interromper o vídeo.
-------------------------------------------------------------------------------*/
:root[data-tema="escuro"] .cabecalho {
  /* Fixo, e não sticky. Sticky continuava a ocupar espaço na página e o
     vídeo começava por baixo dele, deixando a barra de fora da imagem.
     Fixo não ocupa nada, por isso o vídeo sobe até ao topo do ecrã e o
     logótipo fica mesmo dentro da imagem. */
  position: fixed;
  left: 0;
  right: 0;
  background-color: transparent;
  background-image: linear-gradient(
    to bottom,
    rgba(3, 6, 10, .58)  0%,
    rgba(3, 6, 10, .34) 46%,
    rgba(3, 6, 10, .12) 78%,
    rgba(3, 6, 10, 0)  100%
  );
  background-size: auto;
}

/* Sobre imagem, tudo a branco. */
:root[data-tema="escuro"] .nav a { color: rgba(255, 255, 255, .78); }
:root[data-tema="escuro"] .nav a[aria-current="page"] { color: #fff; }
:root[data-tema="escuro"] .marca__cor { display: none; }
:root[data-tema="escuro"] .marca__branco { display: block; }
.marca__branco { display: none; }

/* A barra de leitura sai da aresta do cabeçalho: ali criava a linha
   horizontal que cortava o vídeo. Passa para o topo absoluto do ecrã, com
   apenas 2px, onde se lê como um detalhe e não como uma separação. */
:root[data-tema="escuro"] .progresso {
  position: fixed;
  top: 0;
  bottom: auto;
  height: 2px;
}

/* As páginas que NÃO abrem com vídeo precisam de espaço em cima, porque o
   cabeçalho deixou de o reservar. As que abrem com vídeo não precisam: o
   vídeo ocupa o ecrã todo e o texto está centrado nele. */
:root[data-tema="escuro"] main:not(:has(> .heroi--video)) {
  /* 124px reservavam quase o dobro do que o cabeçalho ocupa (68px). Agora são
     os 68 mais uma folga curta - o resto do ar vem do padding da secção. */
  padding-top: 92px;
}

.cabecalho {
  position: sticky;
  top: 0;
  z-index: 50;
  background-color: var(--fundo-cor);
  background-image: var(--fundo);
  /* NÃO se usa background-attachment: fixed aqui. O cabeçalho tem transform
     (para recolher) e will-change, e qualquer um dos dois faz o browser
     prender o fundo "fixo" ao próprio elemento em vez do ecrã - o alinhamento
     partia-se logo.
     Em vez disso, desenha-se o gradiente com a ALTURA DO ECRÃ e ancorado no
     topo. O cabeçalho mostra assim a fatia de cima desse gradiente, que é
     exatamente a mesma fatia que o corpo da página mostra por trás dele. */
  background-size: 100% 100svh;
  background-position: 0 0;
  background-repeat: no-repeat;
  /* Recolhe ao descer e volta ao subir. A subida é mais rápida do que a
     descida de propósito: quando alguém procura o menu, quer-o já. */
  transition: transform 460ms var(--e-out);
  will-change: transform;
}
.cabecalho-oculto .cabecalho {
  transform: translate3d(0, -100%, 0);
  transition: transform 340ms cubic-bezier(.4, 0, .68, .06);
}
/* SEM backdrop-filter. Havia aqui um saturate(140%) blur(8px), e era ele o
   verdadeiro culpado de o cabeçalho continuar a notar-se: saturava e
   desfocava o que passava por trás, por isso o cabeçalho ficava sempre um
   tom acima do resto da página.
   Agora que ele pinta exatamente o mesmo gradiente do corpo, o efeito de
   vidro é não só desnecessário como contraproducente. E poupa-se de caminho
   a operação mais cara que havia no site. */

.cabecalho__topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 68px;
}

/* O LOGÓTIPO E O MENU DESCEM UM POUCO NO TELEMÓVEL (7 out 2026).
   Estavam centrados, mas numa barra de 68px um logótipo de 46 só tem 11px de
   ar em cima - e, com a página a começar no topo do ecrã, lia-se como estando
   colados à aresta.
   E NÃO CUSTA NADA ao resto da página, o que não era garantido: como a caixa
   mede pelo contorno, o min-height de 68px já conta com o recuo. A barra não
   cresce um pixel - o que acontece é o conteúdo descer dentro dela, de 11px
   de ar em cima para 17. Por isso não há reservas a acertar em lado nenhum;
   cheguei a escrevê-las e estavam a empurrar as páginas interiores 12px para
   baixo sem razão nenhuma.
   No computador não se aplica: lá a barra tem 88px e o ar já chega. */
@media (max-width: 1199px) {
  .cabecalho__topo { padding-top: 12px; }
}

/* O logótipo tem presença a sério. Era pequeno de mais e fazia o topo
   parecer um cabeçalho por acabar. */
.marca {
  position: relative;
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  /* A ampliação ao passar o rato mudou-se da imagem para o conjunto: o risco
     pintado por cima é um irmão posicionado, e se só a imagem crescesse os dois
     saíam do sítio um do outro. */
  transition: transform 420ms var(--e-out);
}
/* 46px e não 40, a pedido dele a 7 out 2026 - "um pouco maior, coisa pouca".
   Fica-se por aqui de propósito: a barra do cabeçalho mede 68px e um logótipo
   de 46 deixa-lhe 11px de ar de cada lado, que é a mesma folga que o botão do
   menu já tem. Mais do que isto obrigava a subir a barra, e a subir com ela a
   reserva que o conteúdo faz para o cabeçalho - ou seja, mexer no telemóvel
   todo por causa de uma coisa pouca. No computador são 56px, lá em baixo. */
.marca img { height: 46px; width: auto; }
@media (hover: hover) { .marca:hover { transform: scale(1.04); } }

/* --- O RISCO DO LOGÓTIPO ----------------------------------------------------
   O risco branco por baixo do "SAFE" passa a ter as cores da marca e a mesma
   faísca que atravessa a barra grande. Não se recorta o PNG: nesse ficheiro o
   risco ocupa as linhas 63 a 71 de 72 - os últimos 12,5% da altura - e vai de
   ponta a ponta, por isso um retângulo simples assenta-lhe exactamente em cima.
   Consequência útil: se por alguma razão isto não pintar, o que se vê por baixo
   é o risco branco original e não um buraco.
-------------------------------------------------------------------------------*/
.marca__risco { display: none; }

:root[data-tema="escuro"] .marca__risco {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 12.5%;
  overflow: hidden;
  background: var(--grad);
  pointer-events: none;
}

/* A faísca. Mesma duração da barra grande para as duas baterem no mesmo
   compasso, mas com atraso diferente - a arrancarem juntas pareciam um
   relógio. Fica estreita e curta: aqui é um detalhe de 50px, não um gesto. */
:root[data-tema="escuro"] .marca__risco::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 38%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .88), transparent);
  transform: translate3d(-160%, 0, 0);
  animation: brilho-marca 7s var(--e-move) 2.6s infinite;
}
@keyframes brilho-marca {
  0%        { transform: translate3d(-160%, 0, 0); }
  32%, 100% { transform: translate3d( 400%, 0, 0); }
}
.pausado .marca__risco::after { animation-play-state: paused; }

/* Seletor de idioma, com bandeiras, no rodapé. Pequeno de propósito: não é o
   que alguém vem cá fazer. A bandeira do idioma ativo fica a cores e as
   outras esbatidas, para se perceber de relance em que idioma se está. */
/* As duas preferências do visitante - idioma e tema - lado a lado no rodapé. */
.rodape__preferencias {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: clamp(28px, 4.4vh, 46px);
}

/* O botão de dia e noite (a lua e o sol) saiu a 2 out 2026. O site passou a ter
   uma versão só, a escura, e o `data-tema="escuro"` é agora escrito direto no
   <html> pelo gerador - não há nada para alternar. Com ele saíram também o
   js/tema.js e o id="tema-escuro" da folha de estilos.
   As regras `:root[data-tema="escuro"]` espalhadas pelo ficheiro ficam: são
   elas que fazem o tema, e passam a estar sempre ativas. */

.idiomas {
  display: flex;
  align-items: center;
  gap: 4px;
}
.idiomas a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  border-radius: 8px;
  text-decoration: none;
  transition: background 200ms var(--e-out);
}
/* As bandeiras inactivas estavam a 42% de opacidade e 25% de saturação. Com a
   portuguesa e a britânica ainda se percebia, mas a espanhola - três faixas
   horizontais lisas - ficava um rectângulo cinzento indistinguível de uma
   barra vazia. Subiu para 62% e 55%: continuam claramente apagadas ao lado da
   activa, mas lêem-se como bandeiras. */
.idiomas svg {
  width: 22px;
  height: auto;
  border-radius: 2.5px;
  opacity: .62;
  filter: saturate(.55);
  transition: opacity 260ms var(--e-out), filter 260ms var(--e-out), transform 260ms var(--e-out);
}
.idiomas a[aria-current="true"] svg { opacity: 1; filter: none; }
@media (hover: hover) {
  /* Era `rgba(255,255,255,.6)`, pensado para o tema claro que já não existe:
     no escuro acendia um quadrado quase branco por baixo da bandeira. */
  .idiomas a:hover { background: rgba(255, 255, 255, .1); }
  .idiomas a:hover svg { opacity: 1; filter: none; transform: translateY(-1px); }
}

/* Tira de navegação. O indicador é UMA régua de 1px que desliza por
   translateX - um só elemento a mover-se, e não um por link. */
.nav {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: clamp(14px, 4vw, 34px);
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.nav::-webkit-scrollbar { display: none; }

/* --- O BOTÃO DE TRÊS TRAÇOS ------------------------------------------------
   Três linhas que viram cruz ao abrir. A animação é feita só com transform,
   por isso é o browser a desenhar e não há recálculo de página nenhum.
-------------------------------------------------------------------------------*/
.menu-botao {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  flex: none;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* ALTURA DE 2px, NÃO 1,5px - e isto não é uma preferência, é aritmética.
   Com 1,5px e folga de 5px, os três traços somavam 14,5px de conteúdo dentro
   de um botão de 44px. Sobra ímpar: o conteúdo começava a 14,75px e cada traço
   calhava numa fracção de pixel diferente. O de cima e o de baixo espalhavam-se
   por três linhas do ecrã (esbatido, cheio, esbatido) e o do meio por duas a
   meio tom - por isso pareciam de espessuras diferentes, apesar de medirem
   todos exactamente 22 x 1,5px.
   Com 2px: 3x2 + 2x5 = 16px, sobra 28px, começa a 14px. Tudo inteiro, os três
   desenhados exactamente da mesma maneira, em qualquer ecrã. */
.menu-botao__traco {
  display: block;
  width: 22px;
  height: 2px;
  border-radius: 1px;
  background: var(--ink);
  transition: transform 380ms var(--e-out), opacity 240ms linear;
}
:root[data-tema="escuro"] .menu-botao__traco { background: #fff; }

/* Aberto: o traço de cima desce e roda, o do meio desaparece, o de baixo
   sobe e roda ao contrário. Fica uma cruz.
   O deslocamento acompanha a nova geometria: os centros ficam a 7px um do
   outro (2px de traço + 5px de folga), não a 6,5px. */
.menu-aberto .menu-botao__traco:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-aberto .menu-botao__traco:nth-child(2) { opacity: 0; transform: scaleX(.4); }
.menu-aberto .menu-botao__traco:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --- A CAMADA DO MENU ------------------------------------------------------ */
.menu {
  position: fixed;
  inset: 0;
  z-index: 45;
  display: flex;
  align-items: center;
  padding: 0 var(--gutter);
  background: rgba(4, 7, 11, .97);
  opacity: 0;
  transition: opacity 420ms var(--e-out);
}
.menu[hidden] { display: none; }
.menu.is-visivel { opacity: 1; }

.menu__lista { display: flex; flex-direction: column; gap: 6px; }

.menu__lista a {
  display: block;
  padding: 14px 0;
  font-size: clamp(2rem, 1.4rem + 2.6vw, 3rem);
  font-weight: 260;
  letter-spacing: -.02em;
  line-height: 1.1;
  color: rgba(255, 255, 255, .62);
  text-decoration: none;
  /* Entram uma a uma, de baixo para cima. */
  opacity: 0;
  transform: translate3d(0, 16px, 0);
  transition: opacity 520ms var(--e-out), transform 520ms var(--e-out), color 240ms linear;
}
.menu.is-visivel .menu__lista a { opacity: 1; transform: none; }
.menu.is-visivel .menu__lista a:nth-child(1) { transition-delay: 60ms; }
.menu.is-visivel .menu__lista a:nth-child(2) { transition-delay: 120ms; }
.menu.is-visivel .menu__lista a:nth-child(3) { transition-delay: 180ms; }
.menu.is-visivel .menu__lista a:nth-child(4) { transition-delay: 240ms; }

.menu__lista a[aria-current="page"] { color: #fff; }
@media (hover: hover) { .menu__lista a:hover { color: #fff; } }

/* Com o menu aberto a página por trás não deve poder deslizar. */
.menu-aberto body { overflow: hidden; }

/* Navegação em texto normal, não em maiúsculas espaçadas. Lê-se mais depressa,
   é maior, e não tem o ar de modelo pré-feito. */
.nav a {
  display: inline-flex;
  align-items: center;
  min-height: 52px;
  white-space: nowrap;
  text-decoration: none;
  color: var(--ink-2);
  font-size: .9375rem;
  font-weight: 380;
  font-stretch: 100%;
  letter-spacing: 0;
  text-transform: none;
  transition: color 180ms linear;
}
.nav a[aria-current="page"] { color: var(--ink); }
@media (hover: hover) { .nav a:hover { color: var(--ink); } }

.nav__indicador {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1.5px;
  width: 1px;              /* a largura real vem do JavaScript, via scaleX */
  background: var(--grad);
  transform-origin: 0 50%;
  transform: translate3d(0, 0, 0) scaleX(0);
  transition: transform 420ms var(--e-move);
  pointer-events: none;
}

/* -----------------------------------------------------------------------------
   8. HERÓI
   Curto por decisão, não por acidente: ocupa cerca de 45% do ecrã para que a
   PRIMEIRA EMPRESA - com nome, sector e os três botões - fique visível sem
   um único scroll. Num site cujo objetivo é dar acesso, fazer o visitante
   rolar antes do primeiro toque é orgulho de designer a custar contactos.

   100svh e não 100vh: no Chrome do Android a barra de endereço recolhe e faz
   a página saltar. A unidade svh mede o ecrã na sua versão mais pequena.
-------------------------------------------------------------------------------*/
/* Sem altura mínima imposta: o herói fica exatamente do tamanho do que tem
   dentro. Forçar 45% do ecrã abria um vazio no meio quando o texto é curto - e abrir vazio por regra é o que faz uma página parecer por acabar. */
.heroi {
  padding-block: clamp(32px, 6vh, 72px) clamp(20px, 3.5vh, 40px);
}

.heroi__eyebrow { margin-bottom: clamp(16px, 3vh, 28px); }

/* SEM limite de medida no telemóvel - e isto foi uma armadilha a sério.
   Havia aqui um `max-width: 16ch`. O `ch` escala com o corpo da letra, por isso
   a largura máxima encolhia exactamente na mesma proporção: baixei o título de
   47px para 26px à procura de uma linha só e "Uma estrutura comum." continuava
   a partir, porque a caixa encolhia com ele. A goteira já faz de medida aqui;
   o 16ch só serve a partir do tablet, onde o ecrã é mais largo do que a medida
   de leitura confortável. */
.heroi__titulo {
  margin-bottom: clamp(20px, 4vh, 36px);
  max-width: none;
}
@media (min-width: 700px) {
  .heroi__titulo { max-width: 16ch; }
}
.heroi__titulo .linha { display: block; }

/* --- A BARRA: a assinatura do sistema ------------------------------------
   É o logótipo a dar à luz a página. Desenha-se da esquerda para a direita,
   e de sete em sete segundos um brilho estreito atravessa-a.               */
.barra {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: var(--grad);
  overflow: hidden;
  transform: scaleX(0);
  transform-origin: 0 50%;
  contain: paint;
}
.barra.is-in {
  transform: scaleX(1);
  transition: transform 900ms var(--e-out) 240ms;
}
.barra::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 26%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.85), transparent);
  transform: translate3d(-140%, 0, 0);
}
.barra.is-in::after { animation: brilho 7s var(--e-move) 1.4s infinite; }
@keyframes brilho {
  0%        { transform: translate3d(-140%, 0, 0); }
  38%, 100% { transform: translate3d( 520%, 0, 0); }
}
.pausado .barra::after { animation-play-state: paused; }

.heroi__subtitulo {
  margin-top: clamp(18px, 3vh, 30px);
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 34ch;
}

.heroi__contador { margin-top: clamp(14px, 2vh, 22px); }

/* -----------------------------------------------------------------------------
   9. AS EMPRESAS - UM ECRÃ INTEIRO CADA
   -----------------------------------------------------------------------------
   Sem cartões, sem molduras, sem fundo a mudar entre secções. Cada empresa
   ocupa a altura toda do ecrã, com o seu vídeo a correr por trás. Quem desce
   a página atravessa as empresas como quem muda de sala, sem nunca ver uma
   fronteira.

   100svh e não 100vh: no Chrome do Android a barra de endereço recolhe e faz
   a página saltar. A unidade svh mede o ecrã na sua versão mais pequena, por
   isso a secção nunca muda de altura a meio do scroll.
-------------------------------------------------------------------------------*/
/* --- O VÍDEO DO TOPO -------------------------------------------------------
   Só entra em ação quando existe um vídeo em dados\site.json. Sem vídeo,
   nenhuma destas regras se aplica e o topo fica exatamente como está.
   O texto, a barra e o espaçamento não mudam - só ganham imagem por trás.
-------------------------------------------------------------------------------*/
/* O título assenta em baixo, não ao centro. Ao centro ficava por cima do meio
   da imagem, que é onde o motivo do vídeo costuma estar, e os dois disputavam
   a atenção; encostado em baixo, a imagem respira em cima e a leitura faz-se
   de uma vez só, do título para a barra e daí para a primeira empresa. */
.heroi--video {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 100svh;
  /* A folga por baixo da barra tem de ser MAIOR do que a parte da entrada que
     ainda se vê quando a primeira empresa já está a entrar no ecrã. Com 89px, ao
     chegar à Dental Power a barra azul do título ficava pendurada no topo, por
     cima da empresa. Com 138px sai de vista antes disso. */
  padding-bottom: clamp(96px, 17svh, 170px);
  overflow: hidden;
  isolation: isolate;
  background: var(--noite);
}

.heroi__media {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
}
/* Os dois vídeos e a imagem de capa ocupam todos o mesmo sítio, sobrepostos.
   Só um está visível de cada vez; a passagem entre eles é uma dissolvência
   de opacidade, que é das poucas coisas que o browser resolve sem repintar
   nada. */
.heroi__media img,
.heroi__media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  filter: brightness(.58) saturate(.95);
}

.heroi__media video {
  z-index: 1;
  opacity: 0;
  transition: opacity 900ms var(--e-out);
}
.heroi__media video.is-pronto { opacity: 1; }

/* O vídeo que ENTRA fica por cima do que sai. É o que permite esbater só um
   deles: o que sai continua opaco por baixo e tapa o fundo até ao fim da
   passagem. A esbater os dois ao mesmo tempo, a meio nenhum estava opaco e
   via-se o fundo através dos dois - era esse o instante preto. */
.heroi__media video.is-frente { z-index: 2; }

/* A capa fica por baixo e sai quando o primeiro vídeo tem imagem. */
.heroi__capa {
  z-index: 0;
  opacity: 1;
  transition: opacity 700ms var(--e-out);
}
.heroi__capa.is-oculto { opacity: 0; }

/* O mesmo véu das empresas: escurece de baixo para cima, para o título se
   ler sempre, seja qual for o vídeo. */
.heroi__veu {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    rgba(3, 6, 10, .90)  0%,
    rgba(3, 6, 10, .72) 22%,
    rgba(3, 6, 10, .42) 48%,
    rgba(3, 6, 10, .26) 74%,
    rgba(3, 6, 10, .38) 100%
  );
}

/* Sobre vídeo, o texto é sempre branco - independentemente do tema. */
.heroi--video .heroi__titulo,
.heroi--video .heroi__titulo .linha { color: #fff; }
.heroi--video .heroi__subtitulo { color: rgba(255, 255, 255, .82); }

.registo { padding: 0; }
.registo .envelope { max-width: none; padding-inline: 0; }

/* 84svh, e já foi 100svh durante dez minutos. A experiência vale a pena ficar
   registada: com o ecrã inteiro por empresa deixa de se ver a seguinte, mas a
   composição de dentro - logótipo, descritor, botões - foi afinada para 84svh e
   a 100svh desarruma-se, com os botões a cair para o fundo do ecrã.
   O cliente experimentou e mandou voltar atrás. */
.empresa {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 84svh;
  overflow: hidden;
  isolation: isolate;
  background: var(--noite);
  contain: layout paint style;
}

/* Dissolve a aresta onde uma secção acaba e a seguinte começa.
   Com cada empresa a ter o seu vídeo, a junção entre duas era uma linha
   horizontal bem visível - a tal "marca atrás do vídeo". Uma faixa escura
   no topo de cada secção faz as duas fundirem-se uma na outra. */
/* O SEGUIMENTO.
   -----------------------------------------------------------------------
   Cada secção esbate-se para preto nas duas pontas: em cima e em baixo.
   Consequência: duas secções seguidas encontram-se sempre em preto, e a
   passagem de uma cor para a outra acontece sem nunca haver uma aresta.

   É o mesmo princípio de uma fita de filme montada com fundidos em vez de
   cortes secos. A cor de cada empresa vive no meio do seu ecrã e dissolve-se
   antes de chegar à vizinha. */
/* AS FAIXAS ENCURTARAM PARA METADE (30 set 2026).
   Estavam a 26% em cima e 34% em baixo. Somadas, eram 60% de um ecrã inteiro a
   preto entre o logótipo de uma empresa e o da seguinte - cerca de 460px num
   telemóvel. O cliente sentiu-o como "um espaço enorme de preto" e tem razão:
   o que separava as secções não era um fundido, era um vazio.

   Podem encurtar porque entretanto todas as empresas passaram a partilhar a
   mesma base azul. Quando as duas cores que se encontram são praticamente a
   mesma, não é preciso apagar as duas até ao preto para esconder a junção -
   bastam uns 15% de cada lado. O fundido continua lá, só que agora é o
   gradiente que ocupa o espaço, em vez do preto. */
.empresa::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 13%;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    var(--noite) 0%,
    rgba(8, 16, 26,.74) 22%,
    rgba(8, 16, 26,.40) 52%,
    rgba(8, 16, 26,.13) 78%,
    rgba(8, 16, 26,0) 100%
  );
}

.empresa::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 16%;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to top,
    var(--noite) 0%,
    rgba(8, 16, 26,.78) 24%,
    rgba(8, 16, 26,.44) 54%,
    rgba(8, 16, 26,.15) 80%,
    rgba(8, 16, 26,0) 100%
  );
}

/* O topo também se dissolve antes de entregar a página à primeira empresa. */
.heroi--video::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 17%;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(
    to top,
    var(--noite) 0%,
    rgba(8, 16, 26,.8) 26%,
    rgba(8, 16, 26,.44) 56%,
    rgba(8, 16, 26,0) 100%
  );
}

/* A partir da quarta, o browser só desenha o que está à vista. */
.empresa:nth-of-type(n + 4) {
  content-visibility: auto;
  contain-intrinsic-size: auto 84svh;
}

/* --- O PLANO DE FUNDO ------------------------------------------------------
   O vídeo (ou a fotografia) cobre a secção inteira. Fica um pouco mais
   escuro em repouso e acende quando a secção está a ser lida - é o mesmo
   gesto do gonfran.pt, mas ligado ao scroll e não só ao rato, porque no
   telemóvel não há rato.
-------------------------------------------------------------------------------*/
.empresa__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}
/* Sobrepostos, e não empilhados. Sem position:absolute, a imagem de capa
   ocupa a altura toda da secção e empurra o vídeo para baixo, fora do ecrã:
   ficava a tocar onde ninguém o via. */
.empresa__media img,
.empresa__media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  /* Presença discreta. O vídeo está lá e percebe-se, mas não compete com o
     nome da empresa: brilho contido e opacidade baixa, um pouco mais forte
     quando a secção está a ser lida.
     A opacidade faz o trabalho melhor do que o brilho, porque deixa o preto
     do fundo atravessar e o resultado fica assente em vez de lavado. */
  /* Brilho muito baixo. O vídeo passa a ser uma presença escura, onde se
     percebe o movimento e a forma sem nunca se conseguir "ler" a imagem.
     Baixar o brilho em vez de baixar só a opacidade dá um resultado assente
     em vez de lavado: a imagem escurece, não se desvanece. */
  filter: brightness(.34) saturate(.7) contrast(1.06);
  transform: scale(1.06);
  transition: filter 900ms var(--e-out), opacity 900ms var(--e-out), transform 1400ms var(--e-out);
}
.empresa.is-ativa .empresa__media img,
.empresa.is-ativa .empresa__media video {
  filter: brightness(.44) saturate(.8) contrast(1.04);
  transform: scale(1);
}

/* O GRADIENTE É DE TODAS AS EMPRESAS, tenham vídeo ou não. Antes só pintava as
   que estavam vazias (`--vazio`), e bastava ligar um vídeo numa delas para essa
   secção sair da família: perdia o azul e ficava a destoar das vizinhas.
   Agora o gradiente é o chão. O vídeo assenta-lhe por cima a 55% de opacidade
   (72% quando a secção está a ser lida), por isso o azul atravessa-o e a imagem
   sai tingida da cor do grupo. Vê-se o movimento sem se perder o seguimento.

   A ordem das camadas importa. A BASE azul do TooSafe é igual em todas as
   empresas e é ela que dá o seguimento de uma secção para a outra: quem faz
   scroll sente que continua no mesmo sítio. A cor do logótipo entra só por
   cima e fraca, o suficiente para distinguir sem quebrar a família. Assim
   nenhuma empresa que entre depois pode partir a coerência, venha o logótipo
   com a cor que vier. */
.empresa__media {
  /* Os raios verticais subiram (62%->80%, 56%->74%, 64%->82%, 58%->76%) para a
     cor chegar perto das duas pontas da secção. Antes morria a meio caminho e,
     como as faixas pretas comiam o resto, sobrava um vazio entre empresas. */
  background:
    /* 1. Assinatura da própria marca - leve, é só um toque. */
    radial-gradient(90% 80% at 76% 26%,
      color-mix(in srgb, var(--marca-1, #0173BE) 16%, transparent), transparent 70%),
    radial-gradient(76% 74% at 22% 84%,
      color-mix(in srgb, var(--marca-2, #26A8E0) 14%, transparent), transparent 74%),
    /* 2. Base comum a TODAS - não depende de nenhuma variável. */
    radial-gradient(92% 82% at 74% 28%, rgba(1, 115, 190, .26), transparent 72%),
    radial-gradient(80% 76% at 20% 86%, rgba(38, 168, 224, .10), transparent 76%),
    /* A base começa e acaba exactamente em --noite, que é a mesma cor para onde
       os dois esbatimentos convergem. Por isso o fim de uma empresa e o começo
       da seguinte encontram-se na mesma cor: não há degrau nem faixa morta,
       só o gradiente a respirar e a voltar. */
    linear-gradient(to bottom,
      var(--noite) 0%,
      #0C1622 42%,
      #0B1420 62%,
      var(--noite) 100%);
}

/* --- O VÉU -----------------------------------------------------------------
   Escurece de baixo para cima. É o que garante que o nome da empresa se lê
   por cima de qualquer vídeo, claro ou escuro. Aclara quando a secção está
   a ser lida, deixando ver melhor a imagem.
-------------------------------------------------------------------------------*/
.empresa__veu {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* ALIGEIRADO (30 set 2026). Este véu foi feito para o nome se ler por cima de
     VÍDEO, e as empresas ficaram sem vídeo - só têm o gradiente, que já é
     escuro por si. A 72% de preto no fundo, estava a apagar a cor exactamente
     na faixa onde fica o nome, e era ele o principal responsável pelo corredor
     preto entre empresas de que o cliente se queixou. Metade chega para o
     branco se ler. Se um dia entrarem vídeos reais, sobe outra vez. */
  background: linear-gradient(
    to top,
    rgba(3, 6, 10, .40)  0%,
    rgba(3, 6, 10, .24) 22%,
    rgba(3, 6, 10, .08) 48%,
    rgba(3, 6, 10, 0)   74%,
    rgba(3, 6, 10, .03) 100%
  );
  transition: opacity 900ms var(--e-out);
}
.empresa.is-ativa .empresa__veu { opacity: .86; }

/* --- O LOGÓTIPO QUE ENTRA A MEIO -------------------------------------------
   Aparece centrado por cima do vídeo, suavemente, quando a secção chega ao
   meio do ecrã. É o gesto do gonfran.pt: primeiro vê-se a imagem, depois
   percebe-se de quem é.
-------------------------------------------------------------------------------*/
/* OS TRÊS LOGÓTIPOS OCUPAM A MESMA CAIXA.
   Os ficheiros têm todos 840px de largura mas alturas diferentes - 578 o da
   Dental Power, 460 o da AC, 408 o da Detalhe Compatível - e, desenhados à
   mesma LARGURA, o da Dental Power ficava 42% mais alto do que o da Detalhe.
   Era isso que os fazia parecer de tamanhos diferentes.

   A caixa passa a ter a proporção do mais baixo dos três, que foi o que ele
   escolheu como referência, e cada logótipo encaixa-se lá dentro sem deformar.
   O resultado é que todos ficam com a MESMA ALTURA e centrados; quem tem mais
   conteúdo na vertical fica mais estreito, que é como se equilibram marcas de
   formatos diferentes.
   Para mudar a referência mexe-se só no aspect-ratio: é o rácio do ficheiro
   que serve de modelo. */
.empresa__marca {
  position: absolute;
  left: 50%;
  /* 50% e não 42%: a meio do painel, a sério. Os 42% vinham de quando o cartão
     era mais alto e o logótipo tinha de fugir dele; sem os títulos e com o
     texto mais pequeno, o meio ficou livre. "Sempre no meio centrado", nos dois
     formatos. */
  top: 50%;
  width: min(58%, 260px);
  aspect-ratio: 840 / 408;
  transform: translate3d(-50%, -50%, 0) scale(.94);
  opacity: 0;
  z-index: 2;
  pointer-events: none;
  transition: opacity 900ms var(--e-out), transform 1100ms var(--e-out);
}
.empresa__marca img {
  width: 100%;
  /* contain e não cover: o logótipo encosta ao lado que lhe calhar e nunca é
     cortado nem esticado. É o que permite dar a todos a mesma altura sem
     deformar nenhum. */
  height: 100%;
  object-fit: contain;
  /* O logótipo entra a branco. Sobre vídeo, a cor de marca compete com a
     imagem e suja; a branco lê-se sempre e parece intencional. */
  filter: none;   /* cores originais, decisao dele a 22 out 2026 */
}

/* A UNICA EXCEPCAO, e e' por necessidade. O logotipo da Detalhe Compativel e'
   azul-escuro sobre transparente, e escuro sobre escuro desaparece - ele proprio
   reparou nisso nos dois formatos. Fica a branco.
   O seletor vai pelo nome do ficheiro: nao precisa de classe nova no HTML nem
   de o gerador saber disto. */
.empresa__marca img[src*="detalhe-compativel"] {
  filter: brightness(0) invert(1) opacity(.95);
}
.empresa.is-ativa .empresa__marca {
  opacity: 1;
  transform: translate3d(-50%, -50%, 0) scale(1);
}

/* --- A COLUNA CENTRADA ------------------------------------------------------
   Deixou de ser uma barra horizontal e passou a ser uma coluna no mesmo eixo do
   logótipo: logótipo, o que a empresa faz, e como lhe chegar. É a ordem por que
   se conhece alguém, e foi o cliente a propô-la - reparou que o nome escrito
   repetia o logótipo que está mesmo por cima.

   Ganho que veio de borla: sem o nome a disputar largura, as bolinhas deixaram
   de estar limitadas. Subiram de 44 para 52px sem nada ceder.
-------------------------------------------------------------------------------*/
.empresa__cartao {
  position: relative;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: calc(100% - (var(--gutter) * 2));
  /* Era clamp(120px, 22vh, 210px) - 179px num telemóvel. Isso deixava um vazio
     enorme entre a barra de uma empresa e o topo da secção seguinte. Ao descer
     para 12svh, a barra aproxima-se do fim da sua secção e o intervalo encurta,
     sem a afastar do logótipo: a secção também encolheu na mesma proporção. */
  margin: 0 var(--gutter) clamp(70px, 12svh, 120px);
  border: 0;
  border-radius: 0;
  overflow: visible;
  background: none;
  color: #fff;
}

/* A frase que diz o que a empresa faz. Fica em caixa normal e peso leve: é
   informação de apoio, não um título - o título é o logótipo. A medida curta
   (27 caracteres) força duas linhas equilibradas em vez de uma linha longa a
   atravessar o ecrã. */
/* --- AS EMPRESAS QUE AINDA NAO ABRIRAM -------------------------------------
   Mesmo painel, mesmo gradiente, mesma composição. O que as distingue são três
   coisas: o logótipo é o da TooSafe, o nome aparece escrito, e levam "Em
   breve" por cima. A terceira não é decoração - sem ela o site estaria a dizer
   que o grupo tem oito empresas a funcionar quando tem três.

   O nome aparece aqui e não nas abertas porque nas abertas o logótipo já o traz
   escrito lá dentro. Com o mesmo logótipo da TooSafe nas cinco, sem o nome
   ficavam cinco painéis iguais.                                             */
/* A .empresa__etiqueta ("Em breve") saiu a 13 out 2026. Não deixei a regra
   órfã: sem o elemento no HTML, era código a dizer que existe uma coisa que
   não existe. */

/* A .empresa__nome saiu a 13 out 2026 com o título. Regra removida também:
   deixá-la era dizer no CSS que existe um elemento que o gerador já não
   escreve. */

/* OS LOGÓTIPOS SÃO TODOS DA MESMA ALTURA, e isto já oscilou duas vezes.
   Cheguei a igualá-los pela ÁREA, por os novos serem quase quadrados (1,19) e
   os antigos largos (1,45 a 2,06): à mesma altura ocupavam menos espaço. A
   conta estava certa e o resultado estava errado - "tá enorme". A razão é que
   área igual não é peso igual: a marca TooSafe é toda de letra cheia e branca,
   e o logótipo da Dental Power é um contorno fino com letra leve. Com a mesma
   área, a TooSafe pesa o dobro no olho.
   Voltou a ser altura igual, que é literalmente o que ele pediu - "igual à da
   Dental Power" - e é o que a caixa partilhada já faz sozinha. Por isso aqui
   não há regra nenhuma: ficou só a nota, para não haver uma terceira volta. */

.empresa__descritor {
  max-width: 27ch;
  margin-bottom: clamp(16px, 2.6vh, 24px);
  font-size: clamp(.9375rem, .88rem + .3vw, 1.125rem);
  font-weight: 330;
  font-stretch: 100%;
  line-height: 1.45;
  letter-spacing: 0;
  text-align: center;
  text-wrap: balance;
  color: rgba(255, 255, 255, .76);
}

/* Diâmetro e folga das três bolinhas, num só sítio.
   Durante muito tempo estes dois números foram uma luta: partilhavam a linha
   com o nome da empresa, e cada píxel de diâmetro custava três à largura do
   texto. Chegaram a descer a 32px e o nome a 17px para caberem os dois.
   Com o nome fora da barra, essa disputa acabou. 52px é confortável para o
   polegar e sobra espaço de lado. */
.empresa__cartao {
  --acao-d: 52px;
  --acao-gap: clamp(14px, 4.2vw, 20px);
}


/* Os três contactos, centrados por baixo do descritor. Sem nada a separá-los:
   chegou a haver dois fios curtos entre eles, o cliente viu-os montados e
   mandou tirar. O anel de cada bolinha já faz a separação sozinho. */
.empresa__contactos {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--acao-gap);
  flex: none;
  border-left: 0;
}

.contacto-btn {
  /* Âncora para o fio e para o rótulo invisível. Sem isto o rótulo, que é
     position:absolute, ia ancorar lá fora no .empresa__cartao. */
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--acao-d, 52px);
  height: var(--acao-d, 52px);
  border: 1px solid rgba(255, 255, 255, .46);
  border-radius: 50%;
  color: rgba(255, 255, 255, .92);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: border-color 320ms var(--e-out), background 320ms var(--e-out),
              color 240ms linear;
}
.contacto-btn svg { width: 23px; height: 23px; flex: none; }

/* LUGAR POR PREENCHER: a Detalhe Compatível ainda não tem Instagram nem
   WhatsApp, e as empresas por abrir não têm nada.

   Durante uns dias este lugar foi desenhado EXACTAMENTE igual aos outros, a
   pedido dele - "vale mais a coerência entre empresas do que esconder o que
   ainda falta". Ele reviu a decisão a 13 out 2026: "mete tipo meio que
   invisíveis, pois ainda não estão aptos para clicar, mas quero que estejam
   lá". E tem razão: um botão com todo o aspecto de funcionar e que não reage
   ao toque lê-se como avaria, não como lugar reservado.

   Atenuado e não escondido. O lugar continua ocupado, por isso os três
   círculos mantêm-se alinhados em todas as empresas - que era o ponto da
   decisão anterior e continua a valer. */
span.contacto-btn {
  pointer-events: none;
  cursor: default;
  opacity: .3;
}

/* O rótulo sai de vista mas fica no código, para os leitores de ecrã. */
.contacto-btn span {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.contacto-btn:active {
  border-color: rgba(255, 255, 255, .9);
  background: rgba(255, 255, 255, .12);
  color: #fff;
}
@media (hover: hover) {
  .contacto-btn:hover {
    border-color: rgba(255, 255, 255, .82);
    background: rgba(255, 255, 255, .08);
    color: #fff;
  }
}

/* Aqui viviam o `.empresa__nome`, o `.empresa__setor` e o `.empresa__site`.
   Saíram todos a 6 out 2026, quando a barra passou a coluna centrada: o nome
   repetia o logótipo, o setor foi substituído pelo descritor (que diz mais com
   as mesmas palavras), e o globo do site deixou de ser um SVG solto dentro do
   bloco de texto para passar a ser o primeiro dos três botões iguais.
   A letra da opção 6 - nome largo e leve, setor estreito e forte - foi-se com
   eles; o descritor tem desenho próprio, mais acima. */

/* Telemóveis estreitos (320-359px: iPhone SE da primeira geração, Androids
   antigos). Aqui o corpo do nome já não desce sozinho - o `clamp` bate no
   mínimo de 1.5rem - e "AC Auto Peças" e "Detalhe Compatível" partiam em duas
   linhas, deixando as três barras com 59, 85 e 105px de altura. Como ele repara
   logo em empresas com aspecto diferente umas das outras, desce-se tudo um
   degrau de uma vez: bolinhas, folgas e corpo de letra.

   ESTE BLOCO TEM DE FICAR AQUI, depois de todas as regras que substitui. Uma
   media query não acrescenta especificidade nenhuma: posto mais acima, era a
   regra normal - por vir depois - que ganhava, e só os valores que não existiam
   lá em baixo é que pegavam. */
@media (max-width: 359px) {
  .empresa__cartao { --acao-d: 46px; --acao-gap: 14px; }
  .contacto-btn svg { width: 21px; height: 21px; }
  /* A 320px nem 33px chegam para "Uma estrutura comum." numa linha: precisa de
     305px e a página só tem 280. */
  .display { font-size: 1.8125rem; }
  /* A 320px "a mesma forma de trabalhar" precisa de descer mais: há 280px de
     largura contra os 335 de um telemóvel normal. */
  .titulo--duplo { font-size: 1.5rem; }

  /* A fotografia dos contactos precisa de dois ajustes num ecrã destes, e os
     dois pela mesma razão: há menos 55px de largura.
     1. A janela sobre a imagem é mais estreita, por isso o símbolo do telefone
        empurra-se para a direita e ficava cortado - sobravam-lhe 18px e ele
        precisa de 25. A imagem anda mais para a direita e ele volta a caber.
     2. O parágrafo de abertura passa de três para quatro linhas e empurra os
        campos 22px para baixo; a fotografia tem de descer o mesmo. */
  .foto--contactos img { object-position: 46% 50%; top: 16.3svh; }
}

/* --- AS LINHAS EM FOSCO: as empresas que aí vêm --------------------------
   Continuam a existir, mas agora numa secção própria sobre fundo escuro,
   depois da última empresa.
-------------------------------------------------------------------------------*/
/* Sobe para junto da última empresa. A margem negativa come o vazio que sobrava
   no fim da secção da Detalhe Compatível - vazio que lá tem de ficar, porque é
   ele que mantém a barra de identificação junto ao logótipo em todas as
   empresas. Encurtar a barra para encurtar o vazio estragava as outras três. */
.preparacao {
  position: relative;
  /* O "Em breve" tem de começar ABAIXO DA DOBRA da última empresa.
     As secções das empresas medem 84svh, por isso quando o deslize assenta numa
     delas sobram 16% de ecrã por baixo - e era aí que o "Em breve" ia espreitar,
     dando a entender que era aquela empresa que estava para abrir. Com 17svh de
     margem fica mesmo por baixo da linha de água. */
  margin-top: clamp(110px, 17svh, 180px);
  padding: clamp(10px, 1.6vh, 20px) var(--gutter) clamp(70px, 12vh, 120px);
  background: var(--noite);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 42%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 0%, #000 42%, transparent 100%);
}

/* Aqui o peso sobe mesmo: é o único rótulo pequeno da página que tem de se
   impor, porque anuncia uma lista inteira. Caixa normal na mesma - o cliente
   rejeita maiúsculas pequenas. */
.preparacao__etiqueta {
  margin-bottom: 22px;
  font-weight: 700;
  color: rgba(255, 255, 255, .72);
}

.futura {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-block: clamp(14px, 2.4vh, 24px);
  border-top: 1px solid rgba(255, 255, 255, .1);
  pointer-events: none;
  user-select: none;
}
.futura:first-of-type { border-top: 0; }

.futura__nome {
  font-size: clamp(1.375rem, 1.05rem + 1.4vw, 2rem);
  font-weight: 260;
  letter-spacing: -.014em;
  color: rgba(255, 255, 255, .8);
  line-height: 1.15;
}
.futura .label { flex: none; color: rgba(255, 255, 255, .45); }

.futura:nth-of-type(1) { filter: blur(1.6px); opacity: .62; }
.futura:nth-of-type(2) { filter: blur(2.6px); opacity: .50; }
.futura:nth-of-type(3) { filter: blur(3.6px); opacity: .40; }
.futura:nth-of-type(4) { filter: blur(4.8px); opacity: .30; }
.futura:nth-of-type(5) { filter: blur(6.2px); opacity: .22; }
.futura:nth-of-type(n + 6) { filter: blur(7.5px); opacity: .16; }

.preparacao__resumo { margin-top: 18px; }

/* -----------------------------------------------------------------------------
   9b. UM DESLIZE, UMA EMPRESA
   -----------------------------------------------------------------------------
   O dedo empurra e a página assenta sozinha na secção seguinte: abre-se o
   site e vê-se o topo; um deslize e está-se na Dental Power; outro e está-se
   na AC Auto Peças. Nunca se fica a meio de duas.

   É "proximity" e não "mandatory" de propósito. Com mandatory, o browser é
   obrigado a assentar sempre numa secção e quem quisesse ler o rodapé ou a
   lista do "Em breve" ficava preso a saltar entre ecrãs. Com proximity só
   assenta quando já vai perto - ajuda quem desliza depressa e não estorva
   quem quer parar a meio.
-------------------------------------------------------------------------------*/
@media (prefers-reduced-motion: no-preference) {
  /* PROXIMITY, e não mandatory. Experimentei o mandatory para garantir que um
     deslize assenta sempre num bloco, e o cliente rejeitou-o de imediato: "este
     empurra-me logo para baixo". É o defeito do mandatory - tira o controlo a
     quem desliza, porque não deixa parar onde a pessoa quer, só onde o site
     deixa. Vale mais ver um bocado da secção seguinte do que lutar com a página.
     Com proximity só assenta quando já vai perto, e quem quer parar a meio
     consegue. */
  html { scroll-snap-type: y proximity; }
  .heroi--video,
  .empresa,
  .preparacao {
    scroll-snap-align: start;
    scroll-snap-stop: normal;
  }
}

/* -----------------------------------------------------------------------------
   9c. SEM FIM DE PÁGINA
   -----------------------------------------------------------------------------
   Depois da última empresa não pode aparecer uma página diferente. O "Em
   breve" e o rodapé continuam na mesma superfície escura das secções, sem
   nenhuma mudança de fundo que anuncie que ali acabou uma coisa e começou
   outra.
-------------------------------------------------------------------------------*/
/* A "Em breve" não pinta fundo nenhum: monta-se sobre o corpo da página, que já
   é var(--noite). Tem de ser assim agora que ela sobe por cima do fim da última
   empresa - se pintasse var(--noite) chapado, cortava a meio o esbatimento dessa
   secção e ficava lá um risco horizontal a dizer "aqui acaba uma coisa e começa
   outra", que é exactamente o que não pode haver. */
:root[data-tema="escuro"] .preparacao {
  background: transparent;
  -webkit-mask-image: none;
          mask-image: none;
}

:root[data-tema="escuro"] .rodape {
  background: var(--noite);
  -webkit-mask-image: none;
          mask-image: none;
}

/* O corpo da página também, senão vê-se o azul do tema por baixo de tudo
   assim que se passa da última empresa. */
:root[data-tema="escuro"] body {
  background-color: var(--noite);
  background-image: none;
}
:root[data-tema="escuro"] .cabecalho {
  background-image: linear-gradient(
    to bottom,
    rgba(3, 6, 10, .62) 0%,
    rgba(3, 6, 10, .34) 48%,
    rgba(3, 6, 10, 0) 100%
  );
}

/* A luz ambiente e o grão deixam de fazer sentido: as secções têm as suas
   próprias cores e estas camadas só as sujavam. */
:root[data-tema="escuro"] .luz,
:root[data-tema="escuro"] .grao { display: none; }

/* -----------------------------------------------------------------------------
   10. SECÇÕES DE CONTEÚDO (Sobre, Contactos)
-------------------------------------------------------------------------------*/
/* O topo e o fundo deixaram de ser iguais. Em cima já há a reserva que o <main>
   faz para o cabeçalho fixo, e somar-lhe mais 73px punha o título a 129px do
   cabeçalho - quase dois dedos de nada em branco antes de a página começar.
   Em baixo a folga mantém-se: é ela que separa o conteúdo do rodapé. */
.seccao { padding-block: clamp(26px, 4.4vh, 58px) clamp(48px, 9vh, 110px); }
.seccao__titulo {
  font-size: var(--step-2);
  font-weight: 260;
  line-height: 1.15;
  letter-spacing: -.01em;
  margin-bottom: 18px;
  max-width: 22ch;
  text-wrap: balance;
}
.seccao__lead {
  font-size: var(--step-1);
  color: var(--ink-2);
  line-height: 1.5;
  max-width: 46ch;
}

/* NAS PÁGINAS INTERIORES A BARRA ENCOSTA AO TÍTULO.
   Estava a meio caminho entre os dois e acabava colada ao parágrafo - lia-se
   como se fosse dele. A barra é a assinatura do TÍTULO (é o gesto do logótipo,
   onde ela fica por baixo do lettering), por isso sobe para junto dele, e o
   parágrafo ganha ar por cima para se ler como um bloco à parte.
   Fica fora do topo da entrada, que já tem o seu próprio equilíbrio. */
.seccao .heroi__titulo { margin-bottom: clamp(10px, 1.6vh, 16px); }
.barra + .seccao__lead { margin-top: clamp(26px, 4vh, 40px); }

/* Título de duas linhas (a página Sobre). Leva corpo próprio porque a segunda
   linha - "a mesma forma de trabalhar" - tem de ficar inteira, e ao tamanho
   geral de 34px partia ao meio. Cabe a 29px. */
.titulo--duplo { font-size: clamp(1.5rem, .7rem + 4.35vw, 5rem); }

.valores { margin-top: clamp(32px, 6vh, 64px); display: grid; gap: 0; }
.valor { padding-block: clamp(22px, 4vh, 34px); border-top: 1px solid var(--rule); }

/* O primeiro pilar não leva fio por cima. Vinha logo a seguir à barra azul e
   ficavam duas linhas horizontais quase encostadas - uma grossa e colorida,
   outra fina e cinzenta - sem nada pelo meio para separarem.
   Os fios ENTRE pilares ficam: esses separam mesmo alguma coisa. */
.valores .valor:first-child { border-top: 0; padding-top: 0; }

/* A lista encosta mais à barra quando vem logo a seguir a ela, sem nada pelo
   meio - é o caso de qualquer página que não tenha parágrafo de abertura. */
.barra + .valores { margin-top: clamp(26px, 4.5vh, 48px); }

/* E o mesmo quando vem a seguir ao parágrafo de abertura, que é o caso do
   Sobre desde 7 out 2026. Sem esta regra a lista cai para o espaçamento base
   de .valores, que é quase o dobro, e abria-se um vazio entre a história e os
   pilares - exactamente o tipo de folga que ele não quer ver. */
.seccao__lead + .valores { margin-top: clamp(26px, 4.5vh, 48px); }
.valor__titulo {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--step-1);
  font-weight: 400;
  margin-bottom: 8px;
}
.valor__texto { color: var(--ink-2); max-width: 52ch; padding-left: 28px; }

/* O visto de cada pilar. Vai no azul da marca e não em verde: o verde entra
   neste site num sítio só, o ícone do WhatsApp, e se começar a aparecer noutros
   lados deixa de significar "WhatsApp" e passa a ser só mais uma cor. O azul
   diz a mesma coisa - isto está garantido - sem abrir a paleta.
   O texto por baixo alinha pela palavra, não pelo visto: daí o recuo de 28px,
   que é a largura do visto mais a folga. */
.valor__visto {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--blue-bright);
}

/* A morada é um link como os outros, mas em duas linhas: rua e número em cima,
   código postal e localidade em baixo.
   O seletor leva o `.contacto a` à frente de propósito: sozinho,
   `.contacto__morada` tem menos peso do que a regra base das fichas e o
   `align-items: center` dela ganhava - a segunda linha saía centrada por baixo
   da primeira em vez de alinhada à esquerda. */
.contacto a.contacto__morada {
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
  padding-block: 4px;
  line-height: 1.35;
}

/* A .contactos__nota saiu a 13 out 2026 com o parágrafo que explicava a linha
   geral. Regra removida também, para o CSS não guardar um elemento que o
   gerador já não escreve. */

/* Fichas de contacto. */
.contactos { margin-top: clamp(32px, 6vh, 56px); display: grid; gap: 0; }
.contacto { padding-block: 22px; border-top: 1px solid var(--rule); }

/* Pela mesma razão dos pilares: a primeira ficha não leva fio por cima. Ali o
   fio não separava nada - era só uma linha solta entre o parágrafo e o
   telefone. Os fios entre fichas ficam. */
.contactos .contacto:first-child { border-top: 0; padding-top: 0; }
.contacto a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--step-1);
  font-weight: 300;
  color: var(--blue-ink);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 240ms var(--e-out);
}
@media (hover: hover) { .contacto a:hover { border-bottom-color: var(--blue-ink); } }

/* -----------------------------------------------------------------------------
   11. RODAPÉ
   A página fecha com o mesmo gesto com que abriu, mas invertido: a barra
   desenha-se da DIREITA para a esquerda. A luz atravessou o documento e voltou.
-------------------------------------------------------------------------------*/
/* O rodapé NÃO tem fundo próprio. Tinha um bloco branco, e era esse bloco que
   criava a fronteira visível a meio da página. Agora deixa passar o mesmo
   fundo contínuo de toda a página, e separa-se apenas por um fio de 1px que
   se desvanece nas pontas - uma separação que se percebe sem cortar a
   superfície. */
.rodape {
  position: relative;
  background: transparent;
  /* Era clamp(48px, 8vh, 90px) em cima. Com isso, e com a margem da grelha por
     baixo, o texto ficava a 124px da linha de separação e a apenas 14px das
     bandeiras - empurrado para o meio do rodapé em vez de pertencer ao topo
     dele. Agora os dois espaços são iguais e o texto encosta à linha. */
  padding-block: clamp(28px, 4.4vh, 56px) 28px;
}
/* O FIO POR CIMA DO RODAPÉ SAIU a 13 out 2026. Já tinha saído do rodapé
   reduzido das páginas interiores; faltava sair da entrada, onde ainda cortava
   uma linha entre a última empresa e o lema. É a mesma objecção que ele já fez
   três vezes a separadores: o que separa ali é a mudança de assunto e o espaço,
   não precisa de um risco a dizê-lo. */
.rodape .barra { transform-origin: 100% 50%; }
.rodape__grelha {
  display: grid;
  gap: clamp(28px, 5vh, 48px);
  /* Zero: esta margem existia para afastar a grelha da barra azul do rodapé, e
     essa barra já não existe. Sem isto somava-se ao padding e duplicava o vazio. */
  margin-top: 0;
}

/* O rodapé reduzido: só bandeiras, direitos e Livro de Reclamações. Sem o lema
   e sem a coluna dos contactos, a respiração de cima era demasiada para o pouco
   que lá está - metade chega. E o seletor de idiomas deixa de precisar da
   margem que o separava do bloco acima, porque já não há bloco acima. */
/* Sem a aresta de topo. Num rodapé que é só bandeiras e obrigações legais, essa
   linha não separava duas coisas - punha-se entre o fim do texto e as bandeiras
   sem haver nada para dividir. O espaço em branco chega para se perceber que
   acabou o conteúdo. Na entrada ela fica: lá o rodapé tem texto próprio e a
   linha marca mesmo onde a página acaba e o rodapé começa. */
.rodape--minimo::before { display: none; }
.rodape--minimo { padding-block: clamp(26px, 4.5vh, 48px) 24px; }
.rodape--minimo .rodape__preferencias { margin-top: 0; }
.rodape--minimo .rodape__legais { margin-top: clamp(20px, 3vh, 32px); }
.rodape__legais {
  margin-top: clamp(32px, 5vh, 52px);
  padding-top: 20px;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  align-items: center;
}
.rodape__legais a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  text-decoration: none;
  color: var(--ink-3);
  transition: color 160ms linear;
}
@media (hover: hover) { .rodape__legais a:hover { color: var(--ink); } }

/* -----------------------------------------------------------------------------
   12. SISTEMA DE REVELAÇÃO
   Os elementos entram quando aparecem no ecrã. O desfasamento entre irmãos
   está escrito como regras :nth-child porque a política de segurança do site
   proíbe style="--i:3" no HTML - é uma das razões mais comuns para um site
   com CSP estrita partir em produção.
-------------------------------------------------------------------------------*/
[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
}
[data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition: opacity 760ms var(--e-out), transform 760ms var(--e-out);
}
.regua.is-in { transform: scaleX(1); transition: transform 520ms cubic-bezier(.22, 1, .36, 1); }

/* O desfoque só existe no titular do herói, onde é um elemento pequeno e o
   efeito de "focar a lente" vale o custo. É removido no fim - nunca fica
   um desfoque a animar continuamente. */
.heroi__titulo .linha {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  filter: blur(6px);
}
.heroi__titulo.is-in .linha {
  opacity: 1;
  transform: none;
  filter: none;
  transition: opacity 760ms var(--e-out), transform 760ms var(--e-out), filter 760ms var(--e-out);
}
.heroi__titulo.is-in .linha:nth-child(1) { transition-delay: 0ms; }
.heroi__titulo.is-in .linha:nth-child(2) { transition-delay: 90ms; }
.heroi__titulo.is-in .linha:nth-child(3) { transition-delay: 180ms; }
.heroi__titulo.is-in .linha:nth-child(4) { transition-delay: 270ms; }

/* Desfasamento genérico entre irmãos - até 12, que cobre 8 empresas com folga. */
.escalona > .is-in:nth-child(1)  { transition-delay: 0ms; }
.escalona > .is-in:nth-child(2)  { transition-delay: 60ms; }
.escalona > .is-in:nth-child(3)  { transition-delay: 120ms; }
.escalona > .is-in:nth-child(4)  { transition-delay: 180ms; }
.escalona > .is-in:nth-child(5)  { transition-delay: 240ms; }
.escalona > .is-in:nth-child(6)  { transition-delay: 300ms; }
.escalona > .is-in:nth-child(7)  { transition-delay: 360ms; }
.escalona > .is-in:nth-child(8)  { transition-delay: 420ms; }
.escalona > .is-in:nth-child(9)  { transition-delay: 480ms; }
.escalona > .is-in:nth-child(10) { transition-delay: 540ms; }
.escalona > .is-in:nth-child(11) { transition-delay: 600ms; }
.escalona > .is-in:nth-child(12) { transition-delay: 660ms; }

/* -----------------------------------------------------------------------------
   13. VÍDEO DE FUNDO (opcional, por empresa)
   O vídeo NUNCA é necessário para o desenho funcionar. Entra como um plano
   atrás da linha da empresa, com a imagem de capa a aparecer primeiro.
   Nunca recortado dentro de um cartão - é isso que o faz acrescentar
   profundidade em vez de partir um sistema feito de tipografia e fios de 1px.
-------------------------------------------------------------------------------*/
/* O BANNER: o logótipo da empresa, grande e quase apagado, atrás da linha.
   Faz o papel do vídeo de fundo enquanto não há fotografias. Dissolve-se para
   a esquerda com uma máscara, para o texto nunca perder legibilidade, e é
   cortado pela direita para dar a sensação de continuar para fora do ecrã -
   que é o que faz parecer um banner e não uma imagem colada. */
/* O logótipo entra MUITO grande e cortado pelas duas pontas, de propósito.
   Um logótipo de fundo que ainda se consegue ler parece uma marca de água mal
   colocada; ampliado a este ponto deixa de se ler como palavra e passa a ser
   forma e cor - lê-se como textura, que é o que se quer atrás de um texto.
   A opacidade é baixíssima: a presença vem do tamanho, não da intensidade. */
/* O banner fica ENQUADRADO dentro do bloco: encostado à direita, com margem,
   e com a altura limitada à do bloco. Antes transbordava e era cortado pela
   margem do ecrã, o que parecia um descuido em vez de uma intenção.
   Dissolve-se para a esquerda, para o texto nunca perder contraste. */
.empresa__banner {
  position: absolute;
  right: clamp(14px, 2.2vw, 30px);
  top: 50%;
  height: 74%;
  max-width: 44%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  transform: translate3d(0, -50%, 0);
  z-index: -1;
  pointer-events: none;
  opacity: .14;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 46%, #000 100%);
          mask-image: linear-gradient(90deg, transparent 0%, #000 46%, #000 100%);
  transition: opacity 720ms var(--e-out), transform 720ms var(--e-out);
}
.empresa__banner img {
  height: 100%;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  object-position: right center;
}

/* Ao ler o bloco, o banner acende e aproxima-se devagar. */
.empresa.is-ativa .empresa__banner {
  opacity: .22;
  transform: translate3d(-8px, -50%, 0);
}

@media (max-width: 720px) {
  /* No telemóvel o texto ocupa quase toda a largura, por isso o banner sobe
     para a metade de cima do bloco e nunca passa por trás dos botões - que
     são a única coisa que ali interessa mesmo. */
  .empresa__banner {
    top: 30%;
    height: 42%;
    max-width: 52%;
    opacity: .12;
  }
  .empresa.is-ativa .empresa__banner {
    opacity: .19;
    transform: translate3d(-4px, -50%, 0);
  }
}

/* O vídeo das empresas ocupa a secção inteira, a toda a força.
   -----------------------------------------------------------------------
   Aqui estava o resto de uma versão anterior, de quando o vídeo era um
   plano discreto atrás de um cartão: uma máscara que o dissolvia para a
   esquerda e uma opacidade de 50%. Sobre o fundo preto da secção nova, esses
   50% davam uma imagem quase invisível - era esse o motivo de a Dental Power
   aparecer preta, com o vídeo a tocar sem se ver.

   O escurecimento passou a ser feito num sítio só, o véu, que é o que
   permite controlá-lo com um valor apenas. */
.empresa__media img,
.empresa__media video {
  opacity: 0;
  transition: opacity 900ms var(--e-out), filter 900ms var(--e-out), transform 1400ms var(--e-out);
}

/* --- O EMBRULHO DO FILME ----------------------------------------------------
   Cada empresa pode ter vários vídeos a passar em sequência. A opacidade que
   deixa o gradiente atravessar a imagem está AQUI, no embrulho, e não em cada
   vídeo - e isso não é arrumação, é o que evita um defeito: durante a passagem
   há dois vídeos sobrepostos, e se cada um fosse semitransparente as duas
   camadas somavam-se e a secção dava um salto de brilho a meio da troca.
   Assim os vídeos trocam entre si a 100% e é o conjunto que aparece esbatido.
-------------------------------------------------------------------------------*/
.empresa__filme {
  position: absolute;
  inset: 0;
  overflow: hidden;
  opacity: .44;
  transition: opacity 900ms var(--e-out);
}
.empresa.is-ativa .empresa__filme { opacity: .58; }

/* A capa fica por baixo dos vídeos e sai quando o primeiro tem imagem.
   O seletor leva o pai à frente de propósito: sozinho, `.empresa__capa` tem
   menos peso do que o `.empresa__media img { opacity: 0 }` lá em baixo - que
   conta um elemento a mais - e a capa nunca chegava a aparecer. */
.empresa__filme .empresa__capa { z-index: 0; opacity: 1; }
.empresa__filme .empresa__capa.is-oculto { opacity: 0; }

/* Dentro do filme é tudo a 100%. O que entra fica por cima do que sai, para
   só um deles se esbater de cada vez - a mesma regra do topo. */
.empresa__filme video { z-index: 1; opacity: 0; }
.empresa__filme video.is-pronto { opacity: 1; }
.empresa__filme video.is-frente { z-index: 2; }

/* Os valores de presença do vídeo. É aqui que se afina, num sítio só.
   Baixo de propósito: o vídeo é ambiente, não é o assunto. O assunto é o
   nome da empresa. Em fotogramas claros, acima de 40% o vídeo passava a
   mandar na secção. */
/* Descido de .55/.72 para .44/.58 no dia em que entrou vídeo numa empresa só:
   a Dental Power ficava muito mais clara do que as vizinhas e via-se o degrau
   na junção. Assim o vídeo lê-se como textura em movimento dentro do azul, e
   não como uma fotografia colada por cima dele. */
/* Estes valores são agora do embrulho (.empresa__filme, mais acima). Aqui fica
   só o caso da fotografia fixa, para as empresas que venham a ter banner em vez
   de filmagens - essa imagem não tem embrulho nenhum e carrega a opacidade. */
.empresa__media > img:not(.is-oculto) { opacity: .44; }
.empresa.is-ativa .empresa__media > img:not(.is-oculto) { opacity: .58; }
.empresa__media > img.is-oculto { opacity: 0 !important; }

/* -----------------------------------------------------------------------------
   14. DESKTOP
   O desktop é o caso derivado. O conceito nasce a 375px.
-------------------------------------------------------------------------------*/
@media (min-width: 720px) {
  /* Em ecrãs maiores as ações alinham-se numa só fila. auto-fit faz com que
     2, 3 ou 4 contactos caibam sem nenhuma regra por número de botões. */
  /* Numa só fila e todos com a mesma largura. A marcação "largo", que no
     telemóvel evita um botão órfão a meia linha, não faz sentido aqui e é
     anulada - senão um dos botões estica e quebra a uniformidade. */
  .acoes { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); max-width: 680px; }
  .rodape__grelha { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
  /* .empresa__corpo e .empresa__meta estavam aqui e saíram a 7 out 2026: eram
     restos da marcação anterior a 6 de Outubro e não existem em nenhuma das
     nove páginas geradas. Não faziam mal, mas faziam acreditar que havia
     alguma coisa escrita para as empresas no computador, e não havia nada. */
  .valores { grid-template-columns: repeat(3, 1fr); gap: 0 clamp(28px, 3vw, 56px); }

  /* O PRIMEIRO PILAR VOLTA A TER FIO E ESPACO.
     Ha' uma regra la' em cima - .valores .valor:first-child - que lhe tira o
     border-top e o padding-top. Em coluna unica isso esta' certo: os tres
     empilham e o primeiro nao precisa de risco por cima, seria uma linha solta
     a abrir a seccao. Mas aqui ficam LADO A LADO, e entao a regra fazia duas
     coisas erradas ao mesmo tempo: o Rigor era o unico sem fio, e subia 34px
     em relacao aos outros dois porque tambem perdia o espaco de cima.
     Era isso que ele via como 'falta o separador no rigor e estar devidamente
     bem formatado tudo' - um so' defeito com duas caras. */
  .valores .valor:first-child {
    border-top: 1px solid var(--rule);
    padding-top: clamp(22px, 4vh, 34px);
  }
  .valor { border-top: 1px solid var(--rule); }
  /* AS FICHAS DE CONTACTO PERDEM OS FIOS em duas colunas.
     Os fios por cima de cada ficha foram desenhados para uma LISTA VERTICAL,
     onde cada um separa uma ficha da anterior e a primeira não leva nenhum.
     Postos numa grelha de duas colunas, essa lógica desfaz-se: na primeira
     fila, o "Telefone" ficava sem fio e o "Email" com fio, e - pior - o fio
     traz 22px de recuo com ele, por isso os dois nem começavam à mesma altura.
     Era isso que se via como barras mal definidas.
     Numa grelha quem separa é o intervalo, não um risco. Os fios saem, o
     recuo sai com eles, e as fichas passam a alinhar pelo topo. */
  .contactos {
    grid-template-columns: repeat(2, 1fr);
    gap: clamp(26px, 3.6vh, 42px) clamp(28px, 3vw, 56px);
  }
  .contactos .contacto {
    border-top: 0;
    padding-block: 0;
  }
  .rodape__grelha { grid-template-columns: 1.4fr 1fr 1fr; }

  /* UMA GRELHA COM UM FILHO SÓ NÃO É UMA GRELHA DE TRÊS COLUNAS.
     O rodapé foi desenhado para três blocos - navegação, contactos, legal - e
     esses saíram a 6 de Outubro. Ficou um filho só, o lema, espremido na
     primeira pista de 1,4fr: 454px num rodapé de 1320, com dois terços de
     ecrã vazio ao lado. Era por isso que o max-width do parágrafo não fazia
     diferença nenhuma - o limite não era ele, era a pista.
     O :not(:has(> * + *)) lê-se "que não tem um segundo filho". Assim, no dia
     em que o rodapé voltar a ter mais blocos, as três colunas voltam sozinhas. */
  .rodape__grelha:not(:has(> * + *)) { grid-template-columns: 1fr; }

  /* E agora o lema pode mesmo usar a largura, com UMA FRASE POR LINHA.
     A quebra estava a cair a meio da segunda frase - "...de negócio. A
     confiança e o" - e ele queria-a onde a frase acaba. Por isso o gerador
     passou a escrever cada frase no seu <span class="linha">, que aqui vira
     bloco. No telemóvel esses spans ficam inline e o parágrafo corre
     exactamente como corria.
     O corpo desce de --step-1 para --step-0, de 22 para 17px, e isso não é
     gosto: a frase mais longa dos três idiomas é a espanhola, com 114
     caracteres, e a 22px precisava de 1452px num contentor que tem 1192. A
     17px cabe. Sem isto, partir pelas frases dava três linhas em vez de duas
     e ficava pior do que estava. */
  .rodape .seccao__lead {
    max-width: none;
    font-size: var(--step-0);
  }
  .rodape .seccao__lead .linha { display: block; }
}

/* =============================================================================
   14b. O COMPUTADOR: AS EMPRESAS LADO A LADO
   -----------------------------------------------------------------------------
   Até 7 de Outubro de 2026 não existia uma única regra de computador para as
   empresas. O conceito nasceu a 375px e no ecrã grande a mesma secção virava
   uma faixa de 1425 por 756: o vídeo esticado de ponta a ponta e o conteúdo,
   278px de texto, perdido no meio. O cliente disse "fica muito esticado" e
   "os vídeos ficam sem qualidade", e as duas queixas são a mesma coisa.

   A PROVA, medida: dos quatro vídeos, três são Reels verticais. Numa faixa
   larga, o recorte de um vídeo vertical mostra 30% do plano - uma tira fina
   pelo meio, ampliada duas vezes e meia. Numa coluna de retrato mostra 90%.
   Não é só uma questão de gosto: a coluna devolve o plano que a faixa deitava
   fora, e por isso resolve a nitidez sem um único ficheiro novo.

   O BREAKPOINT É 1200px DE LARGURA E 640px DE ALTURA, e os dois têm conta.
   Largura: a composição aprovada no telemóvel tem 335px úteis. Para a coluna
   não ficar mais apertada do que isso, com respiro próprio de 28px de cada
   lado, precisa de 390px; três delas mais as goteiras dão 1230. A 1024px as
   colunas ficariam com 300px úteis - mais apertadas do que o telemóvel, ou
   seja pior do que a faixa de hoje. Altura: a 620px de janela, 84svh dão
   521px e a coluna deixa de ser retrato. Abaixo disso fica a pilha aprovada,
   que num ecrã baixo também é a melhor das duas.

   ESTE BLOCO TEM DE FICAR AQUI, depois de tudo o que substitui: uma media
   query não acrescenta especificidade nenhuma.
============================================================================= */
@media (min-width: 1200px) and (min-height: 640px) {

  /* A GRELHA DAS EMPRESAS.
     Passou de tira a grelha a 13 out 2026, quando as cinco empresas por abrir
     deixaram de ser uma lista de nomes e passaram a ter painel proprio: oito
     paineis numa fila so' nao fazem fila, fazem corredor.
     Antes disto houve uma tira encostada a' esquerda com o "Em breve" cortado
     na borda, e antes dela uma grelha de tres colunas centrada que ele recusou
     por ficar "uma ilha com espaco a volta". A diferenca para essa primeira
     grelha e' que agora a grelha tem conteudo que chegue para a justificar. */
  .registo { position: relative; }
  .registo .envelope {
    display: grid;
    grid-template-columns: repeat(var(--colunas, 4), minmax(0, 1fr));
    gap: clamp(10px, 1vw, 18px);
    max-width: var(--max);
    padding-inline: var(--gutter);
  }

  /* QUANTAS COLUNAS, pelo numero de paineis que o gerador escreve no HTML.
     A tabela esta' escrita para nunca deixar um painel orfao numa fila so' para
     ele: com 8 da' 4 e 4. O CSS nao consegue contar filhos para isto - repeat()
     nao aceita um calc() como contagem - e auto-fit nao serve porque faria a
     contagem seguir a largura da JANELA em vez do numero de paineis. */
  .registo[data-empresas="1"] { --colunas: 1; }
  .registo[data-empresas="2"],
  .registo[data-empresas="4"] { --colunas: 2; }
  .registo[data-empresas="3"],
  .registo[data-empresas="5"],
  .registo[data-empresas="6"],
  .registo[data-empresas="9"] { --colunas: 3; }
  .registo[data-empresas="7"],
  .registo[data-empresas="8"],
  .registo[data-empresas="10"],
  .registo[data-empresas="11"],
  .registo[data-empresas="12"] { --colunas: 4; }

  /* A ALTURA DESCE NA GRELHA, e tem conta feita. Os 84svh foram escolhidos
     para uma empresa por ecra; com duas filas davam 1512px de seccao e obrigavam
     a percorrer ecra e meio so' de empresas. A 54svh cada painel mede cerca de
     318 por 486 numa janela de 900 - proporcao 0,65, retrato, que e' o que o
     formato dos videos pede - e uma fila inteira cabe de uma vez.
     Sem encaixe em eixo nenhum: cada painel deixa de ser paragem propria, senao
     os quatro de uma fila davam paragens coincidentes no mesmo sitio. A paragem
     da pagina e' a grelha inteira. */
  .empresa { min-height: 54svh; }
  .empresa { scroll-snap-align: none; }

  /* O LOGÓTIPO SAI DA POSIÇÃO ABSOLUTA E ENTRA NA COLUNA.
     Esta foi a correcção de 13 out 2026, e o defeito era feio: o logótipo
     estava ancorado a 42% da altura do painel e o cartão crescia de baixo para
     cima. Num painel de 84svh nunca se tocavam; a 54svh, e com o cartão das
     empresas por abrir a levar mais duas linhas - a etiqueta e o nome -
     passaram a sobrepor-se. Medido antes de corrigir: 18px nas abertas, 25 nas
     por abrir, e 55px na Real Estate, cujo nome parte em duas linhas. O texto
     ficava escrito por cima do logótipo.

     Ajustar a percentagem resolvia este caso e voltava a partir ao primeiro
     texto que mudasse de tamanho. Por isso o logótipo deixa de flutuar: o
     painel passa a ser uma coluna e os dois empilham-se, logótipo em cima,
     cartão em baixo. Assim não há sobreposição POSSÍVEL, seja qual for o
     comprimento do nome ou do descritivo.

     No telemóvel não se toca: lá o painel tem 84svh, há espaço de sobra e a
     posição flutuante é o que põe o logótipo no meio do vídeo. */
  /* O LOGÓTIPO VOLTA A FLUTUAR, CENTRADO NO PAINEL.
     Tinha-o posto em coluna há umas horas, para resolver a sobreposição com o
     cartão. Resolveu, mas colou-o ao texto e deixou o terço de cima do painel
     vazio - "temos que definir o logo sempre no meio, sempre no meio centrado".
     O que mudou entretanto foi o cartão: sem os títulos e com o texto mais
     pequeno, encolheu o suficiente para o logótipo caber no meio sem lhe tocar.
     Conta, num painel de 486px: o cartão ocupa dos 322 aos 486, e o logótipo
     centrado a 50% fica entre os 211 e os 274. Sobram 48px entre os dois.

     E ao voltar a ser posicionado, a proporção volta a resolver-se no próprio
     contentor - um elemento posicionado com largura definida tira dali altura
     definida. Por isso o aspect-ratio na imagem, que era o remendo de que a
     coluna precisava, deixa de ser preciso.
     Fica igual ao telemóvel, que é o que ele pediu para os dois. */

  /* MAIS PEQUENO E MAIS BAIXO, a pedido dele: "todos os textos mais pequenos
     na parte das empresas, deixa mais baixo, para ser minimalista".
     O descritivo descia de 18,3px para 15, que num painel de 287px de largura
     é o que o deixa resolver-se em duas linhas curtas em vez de três. E o
     cartão encosta-se mais ao fundo - de 63 para 34px - o que abre o painel e
     deixa o vídeo respirar, que é de onde vem o ar da composição. */
  .empresa__cartao { margin-bottom: clamp(26px, 3.8svh, 38px); }
  .empresa__descritor {
    font-size: clamp(.8125rem, .78rem + .17vw, .9375rem);
    margin-bottom: clamp(12px, 1.8vh, 18px);
  }

  /* O PAINEL.
     O cartão pagava a goteira da página duas vezes dentro de si - e --gutter
     é 5% da largura do ECRÃ, não da caixa onde ele está. Numa faixa de 1425px
     isso era razoável; numa coluna de 475 comia 128px, 27% do painel. O
     respiro passa a ser da secção e à medida dela.

     width: 100% e não auto: o cartão é item de uma caixa flexível em linha, e
     com auto encolhia até à medida do descritor e ficava encostado à esquerda
     da coluna em vez de ao centro dela. Com 100% ocupa a coluna e são os
     filhos que se centram, que é o que o align-items: center lá dentro já faz
     no telemóvel. */
  .empresa__cartao {
    width: 100%;
    margin-inline: 0;
  }
  .empresa {
    padding-inline: clamp(24px, 2.2vw, 40px);
  }

  /* OS ESBATIMENTOS DE JUNÇÃO encurtam.
     Existem para casar o fim de uma empresa com o princípio da seguinte, e em
     fila já não há seguinte por baixo - há vizinhos ao lado. A 13% e 16% de um
     painel de 756px gastavam 219px, 29% da altura da coluna, a escurecer para
     esconder uma junção que ali deixou de existir; o de baixo caía mesmo por
     cima dos botões. A fila só precisa de casar com o topo e com o "Em breve".
     A separação lateral faz-se com o gap, que mostra o --noite do corpo - a
     mesma cor para onde a base do gradiente já converge, por isso separa sem
     introduzir cor nenhuma. */
  .empresa::after  { height: 7%; }
  .empresa::before { height: 9%; }

  /* O DESLIZE VERTICAL passa a apontar à fila.
     Em coluna, as três empresas ficam com o mesmo topo e davam três pontos de
     paragem coincidentes no mesmo sítio. Ficam três paragens limpas: topo,
     fila, rodapé. Continua proximity - mandatory está fora de questão.

     O "scroll-snap-align: none" das empresas que estava aqui SAIU, e custou
     uma hora a perceber porquê: vinha depois da regra que lhes dá o encaixe
     lateral, com o mesmo peso, e ganhava. Resultado: o único ponto de encaixe
     da tira passava a ser o bloco "Em breve", e a tira abria já deslizada até
     ao fim, com as empresas fora do ecrã. O eixo vertical é desligado onde
     deve ser, no primeiro valor do "none start" lá em cima. */
  .registo {
    scroll-snap-align: start;
    scroll-snap-stop: normal;
  }

  /* O LOGÓTIPO GANHA PRESENÇA no computador: 40 para 56px de altura.
     Os 40px foram afinados para um ecrã de telemóvel, onde ocupam um oitavo
     da largura. Num ecrã de 1440 ficavam perdidos ao canto.
     A barra do cabeçalho sobe de 68 para 88px para o acompanhar - sem isso o
     logótipo encostava-se às arestas e deixava de ter ar à volta. E as duas
     reservas que dependem dessa altura sobem com ela, senão o conteúdo das
     páginas interiores passava a ficar por baixo do cabeçalho. */
  .marca img { height: 56px; }
  .cabecalho__topo { min-height: 88px; }

  /* O MENU ACOMPANHA. Testei-o aberto no computador: funciona, fica centrado
     na vertical e alinhado pela mesma goteira do resto da página, sem nada
     sobreposto. O que não acompanhava era a escala - quatro ligações de 48px
     num ecrã de 1440 liam-se como um menu de telemóvel esticado. A 64px o
     ecrã inteiro passa a ter uma razão para estar coberto. */
  .menu__lista a { font-size: 4rem; padding-block: 16px; }
  :root[data-tema="escuro"] main:not(:has(> .heroi--video)) { padding-top: 116px; }
  html { scroll-padding-top: 116px; }

  /* O TÍTULO DO TOPO desce de corpo e deixa de partir a última linha.
     A 1440px o corpo geral dava 93px, e com a medida de 16ch que vinha dos
     700px a frase "Uma estrutura comum." não cabia numa linha - sobrava
     "comum." sozinho em baixo, que é o que ele nunca deixa passar.
     São as duas pontas do mesmo problema: menos corpo e mais medida. A medida
     está em ch, que acompanha o corpo da letra, por isso 22ch chegam sempre
     para os 20 caracteres da linha mais longa, seja qual for o tamanho. */
  .heroi--video .heroi__titulo {
    font-size: clamp(2.75rem, 1.2rem + 3.1vw, 4.5rem);
    max-width: 22ch;
  }

}


/* -----------------------------------------------------------------------------
   15. TRANSIÇÕES ENTRE PÁGINAS
   Duas linhas de CSS que fazem quatro páginas separadas parecerem um só
   objeto contínuo. Onde o browser não suporta, simplesmente não acontece - nada parte.
-------------------------------------------------------------------------------*/
@view-transition { navigation: auto; }

::view-transition-old(root) { animation: sair 180ms var(--e-press) both; }
::view-transition-new(root) { animation: entrar 340ms var(--e-out) both; }
@keyframes sair   { to   { opacity: 0; transform: translate3d(0, -8px, 0); } }
@keyframes entrar { from { opacity: 0; transform: translate3d(0, 10px, 0); } }

/* O cabeçalho e a barra atravessam a navegação sem piscar. */
.cabecalho { view-transition-name: cabecalho; }

/* -----------------------------------------------------------------------------
   16. MOVIMENTO REDUZIDO
   Quem ativou esta preferência no sistema costuma fazê-lo por enxaquecas ou
   perturbações vestibulares. O site continua bonito - a composição, as réguas
   e o gradiente mantêm-se. Só o movimento desaparece.
-------------------------------------------------------------------------------*/
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
  }

  [data-reveal],
  .heroi__titulo .linha {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }
  .barra, .regua { transform: scaleX(1) !important; }
  .empresa::before { transform: scaleY(1) !important; }
  .barra::after, .luz, .marca__risco::after { display: none; }
  .empresa__media video { display: none; }

  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}

/* =============================================================================
   17. CAMADA DE MOVIMENTO
   -----------------------------------------------------------------------------
   Tudo o que está aqui é movimento ligado ao SCROLL. A diferença em relação a
   uma animação normal é que o browser moderno calcula estas fora da thread
   principal - o mesmo sítio onde corre o JavaScript. Resultado: o movimento
   acompanha o dedo em tempo real e não engasga, mesmo num telemóvel modesto.

   Onde o browser não suporta (Safari mais antigo, WebViews antigas), nada
   disto acontece e o site continua exatamente igual, revelado pelo sistema
   da secção 12. É melhoria progressiva: nunca há um estado partido.
   ========================================================================== */

/* --- Barra de progresso de leitura ---------------------------------------
   A barra do logótipo torna-se o indicador de quanto falta da página. É o
   mesmo elemento gráfico a ganhar uma terceira função. */
/* A barra do logótipo vive na aresta inferior do cabeçalho e ali acumula
   duas funções: é a assinatura gráfica da marca sempre visível, e enche-se
   da esquerda para a direita à medida que se lê a página. Um só elemento,
   duas leituras - e é o gesto que o cliente identificou como o mais forte
   do site. */
.progresso {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  z-index: 1;
  background: var(--grad);
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
}

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {

    .progresso {
      animation: progredir linear both;
      animation-timeline: scroll(root block);
    }
    @keyframes progredir { to { transform: scaleX(1); } }

    /* --- A etiqueta de setor entra pela direita ------------------------
       view() liga a animação à passagem do elemento pelo ecrã: entra quando
       assoma em baixo e fica assente a meio. */
    .empresa__meta .label:last-child {
      animation: entrarDireita linear both;
      animation-timeline: view();
      animation-range: entry 6% entry 52%;
    }
    @keyframes entrarDireita {
      from { opacity: 0; transform: translate3d(22px, 0, 0); }
      to   { opacity: 1; transform: none; }
    }

    /* --- O número do índice sobe ---------------------------------------- */
    .empresa__meta .label:first-child {
      animation: subirIndice linear both;
      animation-timeline: view();
      animation-range: entry 4% entry 46%;
    }
    @keyframes subirIndice {
      from { opacity: 0; transform: translate3d(0, 14px, 0); }
      to   { opacity: 1; transform: none; }
    }

    /* --- As ações entram em cascata -------------------------------------
       Cada botão arranca um pouco depois do anterior, por deslocar a janela
       de scroll em que reage. É a cascata feita sem uma única linha de JS. */
    .acoes .acao {
      animation: subirBotao linear both;
      animation-timeline: view();
    }
    .acoes .acao:nth-child(1) { animation-range: entry 2% entry 34%; }
    .acoes .acao:nth-child(2) { animation-range: entry 5% entry 37%; }
    .acoes .acao:nth-child(3) { animation-range: entry 8% entry 40%; }
    .acoes .acao:nth-child(4) { animation-range: entry 11% entry 43%; }
    .acoes .acao:nth-child(5) { animation-range: entry 14% entry 46%; }
    @keyframes subirBotao {
      from { opacity: 0; transform: translate3d(0, 18px, 0); }
      to   { opacity: 1; transform: none; }
    }

    /* --- O vídeo de fundo desliza mais devagar do que a página ----------
       Parallax verdadeiro: o plano de trás move-se a outra velocidade, o que
       dá profundidade sem uma única sombra. */
    .empresa__media {
      animation: parallax linear both;
      animation-timeline: view();
      animation-range: cover;
    }
    @keyframes parallax {
      from { transform: translate3d(0, -8%, 0) scale(1.12); }
      to   { transform: translate3d(0,  8%, 0) scale(1.12); }
    }

    /* --- As linhas em fosco afundam-se ao sair --------------------------
       Reforça a leitura de "ainda não chegaram": afastam-se enquanto se
       rola por cima delas. */
    .futura {
      animation: afundar linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 60%;
    }
    @keyframes afundar {
      from { opacity: 0; transform: translate3d(0, 30px, 0) scale(.97); }
      to   { opacity: 1; transform: none; }
    }

    /* --- O rodapé sobe para receber a página ---------------------------- */
    .rodape__grelha > * {
      animation: subirBotao linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 70%;
    }
  }
}

/* --- Efeito magnético nos botões (só rato) --------------------------------
   As variáveis --mx e --my são escritas pelo JavaScript a partir da posição
   do ponteiro. O botão inclina-se ligeiramente na direção do cursor, como se
   fosse atraído. Nunca acontece em ecrãs táteis. */
@media (hover: hover) and (pointer: fine) {
  /* O efeito magnético e a subida ao passar o rato partilham o mesmo
     transform, senão um anulava o outro. --lift é posto pela regra de hover. */
  .acao {
    transform: translate3d(
      calc(var(--mx, 0) * 3px),
      calc(var(--my, 0) * 3px + var(--lift, 0px)),
      0
    );
    transition: transform 320ms var(--e-out), background 320ms var(--e-out), color 200ms linear;
  }
  .acao:active {
    transform: translate3d(
      calc(var(--mx, 0) * 3px),
      calc(var(--my, 0) * 3px),
      0
    ) scale(.985);
  }

  /* --- A secção da empresa reage ao rato ------------------------------- */
  .empresa:hover::before { transform: scaleY(1); }
}

/* --- Sublinhado que cresce nos links de texto ---------------------------- */
.contacto a, .rodape__lista a {
  position: relative;
}
.contacto a::after, .rodape__lista a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 8px;
  height: 1px;
  background: var(--grad);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 420ms var(--e-out);
}
@media (hover: hover) {
  .contacto a:hover::after, .rodape__lista a:hover::after { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
  .progresso { display: none; }
  .acao { transform: none !important; }
}

/* -----------------------------------------------------------------------------
   18. IMPRESSÃO
-------------------------------------------------------------------------------*/
@media print {
  .luz, .nav__indicador, .barra::after, .empresa__media,
  .marca__risco { display: none !important; }
  .cabecalho { position: static; }
  body { background: #fff; color: #000; }
  [data-reveal], .heroi__titulo .linha { opacity: 1 !important; transform: none !important; filter: none !important; }
  .acao::after { content: " (" attr(href) ")"; font-size: 9px; }
}

/* -----------------------------------------------------------------------------
   18. A PAGINA DE ERRO (404.html)
   -----------------------------------------------------------------------------
   Uma so pagina, na raiz, nos tres idiomas ao mesmo tempo: quem cai num
   endereco que nao existe pode vir de qualquer um deles e nao ha como saber.
   Sem cabecalho nem rodape - quem chega aqui quer uma saida, nao um site.
   O ficheiro tem de existir: o .htaccess aponta-lhe o ErrorDocument de 404 e de
   403, e um ErrorDocument para um ficheiro que nao existe faz o Apache
   responder 500 ao site inteiro.
-------------------------------------------------------------------------------*/
.erro {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100svh;
  padding-block: clamp(40px, 8vh, 80px);
}
.erro__caixa {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(28px, 5vh, 48px);
  text-align: center;
}
.erro__marca { display: block; }
.erro__marca img { height: 46px; width: auto; }

.erro__bloco + .erro__bloco {
  padding-top: clamp(22px, 3.5vh, 34px);
  border-top: 1px solid var(--rule);
}
.erro__titulo {
  font-size: var(--step-1);
  font-weight: 320;
  color: var(--ink);
  margin-bottom: 6px;
}
.erro__texto {
  font-size: var(--step-0);
  color: var(--ink-2);
  max-width: 44ch;
  margin-inline: auto;
}
.erro__voltar {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: 10px;
  color: var(--blue-ink);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 200ms var(--e-out);
}
@media (hover: hover) {
  .erro__voltar:hover { border-bottom-color: currentColor; }
}


/* =============================================================================
   >>> TIRA DAS EMPRESAS NO COMPUTADOR - 22 out 2026 <<<
   Apagar tudo entre esta marca e a de fim devolve o desenho anterior.
   ========================================================================== */
/* =============================================================================
   A TIRA DAS EMPRESAS NO COMPUTADOR
   -----------------------------------------------------------------------------
   Desenhada a partir da referencia que ele mandou a 22 out 2026 ("assim que tem
   que ser"). Medida nessa imagem: cinco paineis ao alto, ENCOSTADOS uns aos
   outros sem intervalo nenhum, imagem a cheio e sem veu, e em baixo uma caixa
   de contorno fino com o nome da empresa em pequeno e o SETOR em grande.
   O racio de cada painel la' e' 0,584 - ou seja, 9:16, que foi o que ele pediu
   por palavras na mesma conversa.

   PORQUE E' QUE ISTO NAO E' O "PARECE O INSTAGRAM" QUE ELE REJEITOU:
   a grelha antiga tinha paineis separados por intervalos, cantos arredondados e
   a imagem apagada a 26% de luz - lia-se como uma galeria de cartoes. Aqui os
   paineis sao contiguos, sangram para fora do ecra e a imagem esta' a cheio:
   le'-se como uma so' superficie que corre, nao como cartoes pousados.

   Tudo dentro do media query do computador. O telemovel nao e' tocado.
   ========================================================================== */
@media (min-width: 1200px) and (min-height: 640px) {

  .registo {
    position: relative;
    /* A altura e' o travao, e a largura sai dela pelo racio do ficheiro de
       video (1080/1920 = 0,5625). Assim o video nunca e' cortado, em ecra
       nenhum, e e' por isso que a conta e' nesta ordem. */
    --tira-alt: clamp(460px, 72svh, 780px);
    --tira-larg: calc(var(--tira-alt) * 0.5625);
  }

  /* --- 1. A TIRA ------------------------------------------------------------
     Sem medida de pagina e sem goteira: a tira sangra para os dois lados. Era
     a moldura preta de 40px de cada lado que ele via como "em volta sim esta
     escuro". Aqui nao ha' volta.
     O encaixe e' nativo (scroll-snap), sem JavaScript entre o gesto e o
     movimento - o atraso de 1 a 2 segundos que ele rejeitou em outubro. */
  .registo .envelope {
    display: flex;
    flex-wrap: nowrap;
    grid-template-columns: none;
    align-items: stretch;
    gap: 0;
    max-width: none;
    width: 100%;
    padding-inline: 0;
    /* O MOVIMENTO E' AGORA UMA ANIMACAO DE CSS, e nao JavaScript a escrever
       scrollLeft fotograma a fotograma. Tentei o caminho do scroll tres vezes
       e parava sempre: basta uma politica de movimento reduzido no sistema, um
       separador em segundo plano ou um scroll-behavior herdado para o travar.
       Uma animacao de transform corre no compositor, nao depende de nada disso
       e nao ha' gesto nenhum - nem o rato por cima - que a possa parar.
       A tira tem 18 paineis (9 + 9 copias), por isso -50% e' exactamente uma
       volta: o que fica no ecra no fim e' igual ao do principio. */
    overflow: visible;
    width: max-content;
    animation: tira-anda 150s linear infinite;
    will-change: transform;
    /* SEM ENCAIXE. A tira anda sempre, devagar (js, secção 9), e um encaixe
       puxava-a para trás a cada fracção de pixel - o movimento contínuo e o
       scroll-snap não podem coexistir. */

    /* O site tem scroll-behavior:smooth no html (linha 185). A tira NAO o pode
       herdar: o movimento continuo escreve scrollLeft a cada fotograma, e com
       o smooth ligado cada uma dessas escrituras vira uma animacao que luta
       com a seguinte - o movimento engasga e parece parado. As setas continuam
       suaves porque pedem behavior:'smooth' explicitamente no scrollTo. */
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .registo .envelope::-webkit-scrollbar { display: none; }

  @keyframes tira-anda {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
  }

  /* O corte passa para a seccao, ja' que o envelope deixou de ter scroll.
     O espaco em baixo e' para o rodape nao comecar colado a' barra de
     navegacao - ele pediu a 22 out que o texto de abertura do rodape
     descesse um pouco. */
  .registo {
    overflow: hidden;
    padding-bottom: clamp(34px, 5svh, 72px);
  }

  /* --- 2. O PAINEL ---------------------------------------------------------
     flex: 0 0 trava a largura. Sem isto o flex encolhia os nove para caberem
     todos no ecra, e voltavam as tiras estreitas.
     Sem cantos arredondados e sem intervalo: e' o que separa esta tira de uma
     galeria de cartoes. */
  .registo .empresa {
    flex: 0 0 var(--tira-larg);
    width: var(--tira-larg);
    min-height: var(--tira-alt);
    height: var(--tira-alt);
    position: relative;
    display: block;
    padding: 0;
    margin: 0;
    border-radius: 0;
    overflow: hidden;
    /* Um fio de luz a separar painel de painel. E' o unico separador, e e' do
       lado de dentro: nao abre intervalo nenhum entre eles. */
    box-shadow: inset -1px 0 0 rgba(255, 255, 255, .10);
  }
  .registo .empresa:nth-of-type(n + 4) { contain-intrinsic-size: auto var(--tira-alt); }

  /* --- 3. A IMAGEM, A CHEIO E SEM VEU --------------------------------------
     O veu existia para o texto branco se ler por cima da filmagem. O texto
     passou para dentro de uma caixa com contorno proprio, portanto o veu ficou
     sem trabalho - e era ele metade do escuro de que ele se queixou.
     Fica so' uma sombra curta no fundo, para a caixa assentar. */
  .registo .empresa__media,
  .registo .empresa__veu { left: 0; right: 0; width: 100%; }
  .registo .empresa__veu { display: none; }
  .registo .empresa::before,
  .registo .empresa::after { display: none; }

  .registo .empresa__filme,
  .registo .empresa.is-ativa .empresa__filme { opacity: 1; }

  /* O brilho desceu um degrau a pedido dele (22 out: "quero menos brilho nos
     videos um pouco"). Desceu tres vezes a 22 out: .86, .74 e finalmente .42, este ultimo com uma razao diferente das outras - nao e' gosto, e' para o logotipo branco se destacar. A queixa foi "um pouco", e a esta
     altura ja' percebi que o escuro a mais e' a queixa que mais vezes voltou
     neste projecto. */
  .registo .empresa__media img,
  .registo .empresa__media video,
  .registo .empresa.is-ativa .empresa__media img,
  .registo .empresa.is-ativa .empresa__media video {
    filter: brightness(.30) saturate(.96) contrast(1.02);
    transform: none;
  }
  .registo .empresa__media > img:not(.is-oculto),
  .registo .empresa.is-ativa .empresa__media > img:not(.is-oculto) { opacity: 1; }

  /* O parallax e' um gesto de scroll VERTICAL: numa tira horizontal arrastava
     a imagem para fora do painel. */
  .registo .empresa__media { animation: none; }

  /* O DEGRADE DE LEVE, que ele pediu de volta a 22 out.
     Nao e' nostalgia: e' o que faz os logotipos brancos lerem-se. Sem ele, um
     logotipo branco por cima de um plano claro - a oftalmologia, o bloco
     operatorio - desaparece. E e' tambem o que irmana os nove: cada filmagem
     tem a sua temperatura de cor, e sem uma luz comum por cima a fila le'-se
     como nove ambientes diferentes em vez de um grupo.
     Duas camadas: o azul da marca por cima de tudo, de leve, e uma subida
     escura so' no fundo para a caixa assentar. */
  .registo .empresa__filme::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 4;
    pointer-events: none;
    background:
      linear-gradient(to top,
        rgba(4, 12, 22, .80)  0%,
        rgba(4, 12, 22, .34) 34%,
        rgba(4, 12, 22, .04) 62%,
        rgba(4, 12, 22, 0)  100%),
      linear-gradient(to bottom,
        rgba(1, 115, 190, .16) 0%,
        rgba(38, 168, 224, .10) 100%);
  }

  /* --- 4. O LOGOTIPO -------------------------------------------------------
     Fica onde esta' na referencia: a meio do painel, por cima da imagem. A
     caixa tem ALTURA FIXA com object-fit contain, que e' o que faz os nove
     sairem do mesmo tamanho - a regra que ele mais repete. */
  .registo .empresa__marca,
  .registo .empresa.is-ativa .empresa__marca {
    position: absolute;
    left: clamp(18px, 1.6vw, 26px);
    right: clamp(18px, 1.6vw, 26px);
    top: 50%;
    bottom: auto;
    width: auto;
    max-width: none;
    height: clamp(72px, 11svh, 104px);
    aspect-ratio: auto;
    top: 42%;
    transform: translateY(-50%);
    opacity: 1;
    margin: 0;
    z-index: 2;
  }
  /* AS CORES ORIGINAIS, pedido dele a 22 out: "mete os logos reais, pf, com as
     cores originais". Ate' aqui eram pintados de branco por um
     brightness(0) invert(1) - util quando o fundo era claro, inutil agora que
     o video esta' a 30% de luz. O seletor leva .registo a' frente para pesar
     mais do que a regra original, que tem duas classes. */
  .registo .empresa__marca img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center;
    filter: none;
  }

  /* SO ESTE A BRANCO. O logotipo da Detalhe Compativel e' azul-escuro sobre
     transparente, e a 30% de luz no video um escuro sobre escuro desaparece.
     Os outros oito tem cor clara que chegue. Nao e' excepcao por capricho:
     e' a unica maneira de ter as cores originais E o logotipo visivel. */
  .registo .empresa__marca img[src*="detalhe-compativel"] {
    filter: brightness(0) invert(1) opacity(.95);
  }

  /* --- 5. A CAIXA DE CONTORNO ----------------------------------------------
     O elemento que na referencia carrega o nome pequeno e o setor grande. */
  .registo .empresa__cartao {
    position: absolute;
    left: clamp(18px, 1.6vw, 26px);
    right: clamp(18px, 1.6vw, 26px);
    bottom: clamp(18px, 1.6vw, 26px);
    top: auto;
    z-index: 3;
    display: block;
    width: auto;
    margin: 0;
    padding: 0;
    border: 0;
    text-align: center;
  }

  /* O NOME DA EMPRESA SAIU a 22 out: "retira os nomes das empresas deixa
     anotacao do que e' apenas". O logotipo ja' traz o nome escrito, por isso
     repeti-lo por baixo era dize-lo duas vezes. Fica so' o setor - e como
     passou a ser o unico texto, herda o peso que o nome tinha, senao ficava
     uma linha perdida num painel deste tamanho.
     Continua a sair no HTML: e' o telemovel que o mostra, e para quem usa
     leitor de ecra o nome continua no aria-label da seccao. */
  /* INVERTIDO a 22 out, a pedido dele: "o bold fica as empresas, em pequeno o
     que eles sao". O nome da empresa passa a ser o que se le' primeiro, e o
     setor desce a legenda. Faz sentido: o nome e' que e' a marca, o setor e'
     a explicacao. */
  .registo .empresa__nome {
    display: none;
    margin: 0 0 clamp(3px, .4svh, 6px) 0;
    font-size: clamp(1rem, .84rem + .55vw, 1.5rem);
    font-weight: 700;
    line-height: 1.16;
    letter-spacing: -.004em;
    color: #fff;
  }

  /* TUDO NUMA LINHA SO, pedido dele a 22 out: "sem 2 linhas, tudo na mesma
     linha". O nowrap garante que nunca parte, e o tamanho e' calculado para o
     setor mais comprido que existe - "Construção e remodelação", 24 caracteres
     - caber na largura util da caixa. Se um setor novo for mais comprido do
     que esse, o nowrap faz com que transborde em vez de partir: e' de
     proposito, porque um texto cortado ve'-se logo e um texto partido em duas
     linhas passa despercebido ate' o cliente reparar. */
  .registo .empresa__setor { display: none; }

  .registo .empresa__descritor {
    display: block;
    margin: 0;
    font-size: clamp(.8125rem, .74rem + .3vw, 1.0625rem);
    font-weight: 400;
    line-height: 1.3;
    letter-spacing: .006em;
    color: rgba(255, 255, 255, .92);
    text-align: center;
    max-width: 30ch;
    margin-inline: auto;
  }

  /* TEXTO IGUAL AO DO TELEMOVEL, pedido dele a 22 out: "que os subtitulos
     sejam iguais ao do telemovel para serem tudo igual em termos de texto".
     Estava a mostrar o setor - "Pecas auto" - e o telemovel mostra o descritor
     - "Frentes completas e componentes mecanicos para automovel". Agora e' o
     descritor nos dois, e o setor fica escondido no computador.
     O nowrap saiu: estes textos sao frases e tem de poder partir. */

  /* Os tres botoes ficam, porque ele foi firme nisso: "em todos mete
     exactamente os botoes igual". Aqui entram dentro da caixa, pequenos e
     alinhados a' esquerda, no lugar onde a referencia tem a seta. */
  .registo .empresa__contactos {
    justify-content: center;
    gap: clamp(12px, 1.1vw, 18px);
    margin-top: clamp(12px, 1.4svh, 18px);
  }
  .registo .empresa__contactos .contacto-btn {
    width: clamp(50px, 3.8vw, 62px);
    height: clamp(50px, 3.8vw, 62px);
  }
  .registo .empresa__contactos .contacto-btn span { display: none; }


  /* O LED EM VOLTA DOS QUE DAO PARA CLICAR.
     Ele pediu isto para se distinguirem dos outros: "destacar bem dos que nao
     da para clicar". O seletor e' `a.contacto-btn` - o gerador escreve <a>
     quando ha' endereco e <span> quando nao ha', por isso a distincao ja'
     estava feita no HTML e nao precisa de classe nova.
     Respira em vez de piscar, e acelera quando o rato chega.
     O halo e' BRANCO: o azul lia-se como um rebordo e ele nao o quis. */
  /* O LED ESTA NA LINHA, nao a' volta do circulo. Ele foi claro a 22 out:
     "basta a linha ter led e nao o circulo". Por isso saiu o box-shadow, que
     era um halo a' volta de tudo, e quem respira agora e' a propria cor do
     contorno - acende e apaga, como um fio de luz. */
  @keyframes btn-led {
    0%, 100% { border-color: rgba(255, 255, 255, .42); }
    50%      { border-color: rgba(255, 255, 255, 1); }
  }
  .registo .empresa__contactos a.contacto-btn {
    animation: btn-led 3.4s ease-in-out infinite;
    border: 1px solid rgba(255, 255, 255, .92);
    box-shadow: none;
  }
  .registo .empresa__contactos a.contacto-btn:hover { animation-duration: 1.2s; }
  /* Os que nao dao para clicar ficam quietos e mais apagados: sem brilho,
     sem contorno vivo, sem promessa nenhuma. */
  .registo .empresa__contactos span.contacto-btn {
    animation: none;
    box-shadow: none;
    opacity: .22;
  }
  /* --- 6. A ENTRADA SUAVE NA TIRA ------------------------------------------
     Ele reparou no corte a direito entre o fundo escuro da pagina e o alto dos
     paineis: "nao pode ser um bloco como tu ves ai, tem que ser algo de leve".
     Tinha razao - o alto dos paineis batia no fundo da pagina sem transicao
     nenhuma, e um corte a direito num sitio onde ha' movimento le'-se como
     erro. Esta rampa entra o fundo da pagina para dentro da tira ao longo de
     uns 90px. Fica por cima dos paineis mas nao apanha o rato. */
  .registo .envelope { position: relative; }

  .registo::before,
  .registo::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    z-index: 4;
    pointer-events: none;
    height: clamp(34px, 5svh, 58px);
  }
  .registo::before {
    top: 0;
    background: linear-gradient(to bottom, rgba(8, 16, 26, .72) 0%, rgba(8, 16, 26, .26) 46%, rgba(8, 16, 26, 0) 100%);
  }
  .registo::after {
    bottom: auto;
    top: calc(var(--tira-alt) - clamp(34px, 5svh, 58px));
    background: linear-gradient(to top, rgba(8, 16, 26, .72) 0%, rgba(8, 16, 26, .26) 46%, rgba(8, 16, 26, 0) 100%);
  }

  /* --- 7. A BARRA DE NAVEGACAO ---------------------------------------------
     No espirito da referencia que ele mandou: bloco centrado, sinais grandes e
     uma legenda curta no meio, onde la' estava o nome da marca. Nada de
     circulos a flutuar por cima da imagem - a navegacao tem lugar proprio. */
  .registo .tira-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(18px, 2vw, 34px);
    padding-top: clamp(22px, 3svh, 38px);
  }

  .registo .tira-seta {
    width: clamp(40px, 3vw, 50px);
    height: clamp(40px, 3vw, 50px);
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    background: none;
    color: #fff;
    cursor: pointer;
    opacity: .5;
    transition: opacity 240ms var(--e-out), transform 240ms var(--e-out);
  }
  .registo .tira-seta svg { width: 100%; height: 100%; }
  .registo .tira-seta:hover,
  .registo .tira-seta:focus-visible { opacity: 1; }
  .registo .tira-seta--tras:hover   { transform: translateX(-3px); }
  .registo .tira-seta--frente:hover { transform: translateX(3px); }
  .registo .tira-seta:active { transform: scale(.92); }
  .registo .tira-seta:focus-visible {
    outline: 2px solid var(--marca-2, #26A8E0);
    outline-offset: 4px;
  }

  /* O LED da legenda, pedido dele a 22 out ("com algum tipo de led"). Nao e'
     brilho fixo: respira devagar, a branco. Oito segundos por ciclo -
     a ideia e' que se perceba que esta' vivo, nao que pisque. Respeita quem
     pediu menos movimento. */
  @keyframes tira-led {
    0%, 100% { text-shadow: 0 0 10px rgba(255, 255, 255, .34), 0 0 26px rgba(255, 255, 255, .16); }
    50%      { text-shadow: 0 0 18px rgba(255, 255, 255, .80), 0 0 44px rgba(255, 255, 255, .40); }
  }

  .registo .tira-nav__dizer {
    animation: tira-led 8s ease-in-out infinite;
    /* MENOS DESTAQUE a 22 out: "nao precisa do bold". Baixou de 600 para 400 e
       o branco recuou um pouco. O tamanho fica - ele pediu-o grande antes, e a
       presenca agora vem da medida e do espaco entre letras, nao do peso. */
    font-size: clamp(1.0625rem, .86rem + .7vw, 1.625rem);
    font-weight: 400;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .82);
    white-space: nowrap;
  }
}

/* O nome e o setor sao para a tira do computador. No telemovel quem fala e' o
   descritor, como sempre foi - esta linha e' o que garante que la' nada muda. */
@media (max-width: 1199px) {
  .empresa__nome,
  .empresa__setor { display: none; }
  .tira-seta { display: none; }
}

/* =============================================================================
   >>> FIM DA TIRA DAS EMPRESAS <<<
   ========================================================================== */
