/* ===========================================================================
   CLM · TIROMA — site público
   ---------------------------------------------------------------------------
   Mobile-first. Construído sobre public/css/tokens.css — este ficheiro não
   escreve valores crus de espaço, cor, raio ou tipo. Se encontrar um, é um bug.

   Ordem: base → layout → secções → componentes → movimento.
   O backoffice tem CSS próprio e não é afectado.
   =========================================================================== */

/* tokens.css é carregado por <link> à frente deste ficheiro — não por @import,
   que serializaria os dois pedidos em vez de os paralelizar. */

/* ===========================================================================
   1. Base
   =========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--surface);
    color: var(--text);
    font-family: var(--font-body);
    font-size: 17px;
    line-height: var(--lh-body);
    -webkit-font-smoothing: antialiased;
    overflow-x: clip;
}

img, svg, video { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

h1, h2, h3, h4 {
    font-family: var(--font-head);
    font-weight: 700;
    color: var(--text-strong);
    line-height: var(--lh-head);
    letter-spacing: var(--tr-tight);
    text-wrap: balance;
    margin: 0;
    overflow-wrap: break-word;
}
h1 { font-size: var(--fs-2xl); line-height: var(--lh-tight); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); }
h4 { font-size: var(--fs-md); }

p { margin: 0; }
p + p { margin-top: var(--sp-4); }

/* Foco visível e consistente — não existia. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: var(--r-sm);
}

::selection { background: var(--red-500); color: #fff; }

/* ===========================================================================
   2. Layout
   =========================================================================== */
.container { width: 100%; max-width: var(--w-page); margin-inline: auto; padding-inline: var(--sp-5); }
.container.narrow { max-width: 880px; }
.container.wide { max-width: var(--w-wide); }

/* --- Texto corrido -------------------------------------------------
   Justificado e sem hifenização, em todo o site. Como as colunas passaram
   a ocupar a largura do enquadramento, há muitas palavras por linha e cada
   espaço estica pouco — é isso que evita os buracos entre palavras.

   Títulos e listas de navegação ficam de fora: justificar um título ou uma
   ligação não faz sentido nenhum. */
.prose,
.prose p,
.lead,
.card p,
.s-body p,
.infra-item p,
.value-item p,
.step p,
.mv-item p,
.team-card .bio,
.comment p,
.benefit-grid .t,
.site-footer .about,
.post-body { text-align: justify; text-wrap: pretty; }

/* Excepção automática, medida na coluna e não no ecrã.
   Numa coluna estreita cabem poucas palavras por linha, e a justificação tem
   de esticar tanto os espaços que abre buracos («simultâneo,    apoiando»).
   Cada bloco de grelha declara-se como contentor e, abaixo de 34rem de
   largura, o texto volta a alinhar à esquerda. Assim a mesma regra serve o
   texto largo e o texto em cartão, sem ter de adivinhar pelo viewport —
   a largura real da coluna depende da grelha, não do tamanho da janela. */
.card, .s-body, .infra-item, .value-item, .step,
.team-card, .comment, .benefit-grid li { container-type: inline-size; }

@container (max-width: 34rem) {
    .card p, .s-body p, .infra-item p, .value-item p, .step p,
    .team-card .bio, .comment p, .benefit-grid .t { text-align: left; }
}

.prose { max-width: var(--w-prose); }
.prose p + p { margin-top: var(--sp-4); }
.prose h3 { margin: var(--sp-6) 0 var(--sp-3); text-align: left; }

.center { text-align: center; margin-inline: auto; }

/* Utilitários de espaço vertical — substituem os estilos inline dispersos. */
.mt-4 { margin-top: var(--sp-4); }
.mt-5 { margin-top: var(--sp-5); }
.mt-6 { margin-top: var(--sp-6); }
.mt-7 { margin-top: var(--sp-7); }

/* Grupo de botões lado a lado. Era escrito à mão em cada página. */
.actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }

/* Limita a linha a uma medida legível. Substitui os max-width inline
   (75ch, 70ch, 820px…) que andavam espalhados pelas vistas. */
.measure { max-width: var(--w-prose); }

/* Painel de formulário: não é a coluna de leitura, é um cartão. Fica com
   largura própria dentro do enquadramento normal da página, para o frame
   ficar alinhado com o resto do site. */
.panel { max-width: 46rem; }

/* Preço ou "sob cotação" em destaque. */
.price { font-family: var(--font-head); font-weight: 700; font-size: var(--fs-lg);
    color: var(--text-strong); }

/* ===========================================================================
   3. Secções — um componente, quatro variantes
   ---------------------------------------------------------------------------
   Antes havia <section>, .section-soft e .page-hero com paddings decididos
   caso a caso. Agora o ritmo vertical vem sempre do mesmo token.
   =========================================================================== */
section, .section { padding-block: var(--section-y); position: relative; }
.section--tight { padding-block: var(--sp-7); }
.section--flush-top { padding-top: 0; }

/* Alternância suave, ainda em claro. */
.section-soft, .section--sunken { background: var(--surface-2); }

/* Superfícies escuras: redefinem os tokens semânticos e nada mais. Todos os
   componentes colocados lá dentro adaptam-se sozinhos. */
.section--dark,
.site-footer,
.cta-panel,
.info-panel {
    --surface:        var(--navy-900);
    --surface-2:      var(--navy-800);
    --surface-raised: rgba(255, 255, 255, .05);
    --text:           #b9c1dd;
    --text-strong:    #ffffff;
    --text-muted:     #9ba6d1;
    --border:         rgba(255, 255, 255, .13);
    --accent-text:    var(--red-400);
    color: var(--text);
}
.section--dark { background: var(--surface); }

/* A passagem entre claro e escuro é uma aresta limpa, sem degradê: chegou a
   experimentar-se um esbatimento de 128px e tirava definição ao ritmo das
   secções. O corte seco é o que dá o registo institucional. */
.section--dark { background-color: var(--navy-900); }

/* A malha de rede vive num canvas por baixo do conteúdo. */
.section--mesh { background-color: var(--navy-900); overflow: hidden; }
.section--mesh > .mesh-canvas { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; }
.section--mesh > .container { position: relative; z-index: 1; }
.page-hero .mesh-canvas { z-index: 0; }

/* Cabeçalho de secção: espaçamento fixo e uma âncora visual que fixa o texto
   — sem ela, os blocos ficam a flutuar. */
.section-head { max-width: var(--w-head); margin-bottom: var(--sp-6); }
.section-head > * + * { margin-top: var(--sp-3); }
.section-head .lead { font-size: var(--fs-md); color: var(--text); }

.kicker {
    display: inline-block; position: relative;
    color: var(--accent-text);
    font-weight: 700; font-size: var(--fs-xs);
    letter-spacing: var(--tr-wide); text-transform: uppercase;
    padding-top: var(--sp-3);
}
.kicker::before {
    content: ""; position: absolute; top: 0; left: 0;
    width: var(--sp-6); height: 2px; background: var(--accent);
}
.kicker.badge { padding: var(--sp-2) var(--sp-4); border-radius: var(--r-pill);
    background: color-mix(in srgb, var(--accent) 14%, transparent); }
.kicker.badge::before { display: none; }

/* Sem `margin: 0` aqui: o reset em `p` já o faz, e declará-lo outra vez neste
   ponto do ficheiro anulava silenciosamente os utilitários .mt-* aplicados a
   um `<p class="lead mt-6">` — mesma especificidade, e este vinha depois. */
.lead { color: var(--text); font-size: var(--fs-md); }

/* ===========================================================================
   4. Cabeçalho do site
   =========================================================================== */
.site-header {
    position: sticky; top: 0; z-index: 40;
    background: rgba(11, 15, 38, .82);
    backdrop-filter: saturate(150%) blur(12px);
    border-bottom: 1px solid rgba(255, 255, 255, .1);
    transition: background var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);

    /* O cabeçalho é navy mas ficava fora do escopo escuro: o --text-muted
       resolvia para o cinzento de fundo claro e o selector de idioma dava
       2.3 de contraste. Agora herda os mesmos tokens das secções escuras. */
    --text: #b9c1dd;
    --text-strong: #ffffff;
    --text-muted: #9ba6d1;
    --accent-text: var(--red-400);
}
.site-header .container {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--sp-4); padding-block: var(--sp-3);
}
.site-header .logo img { height: 34px; width: auto; }
.site-header.scrolled { background: rgba(11, 15, 38, .96); box-shadow: var(--sh-2); }

.nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; padding: 0; cursor: pointer;
    border: 1px solid rgba(255, 255, 255, .18); border-radius: var(--r-sm);
    background: transparent; color: #fff;
}
.nav-toggle svg { width: 22px; height: 22px; }
.nav-toggle .icon-close { display: none; }
.site-header.nav-open .nav-toggle .icon-open { display: none; }
.site-header.nav-open .nav-toggle .icon-close { display: block; }

.site-nav {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    background: var(--navy-900); border-bottom: 1px solid rgba(255, 255, 255, .12);
    padding: var(--sp-2) var(--sp-5) var(--sp-5);
}
.site-header.nav-open .site-nav { display: block; }
.site-nav a {
    display: block; padding: var(--sp-3) 0;
    color: #dfe4f4; font-weight: 600; font-size: var(--fs-md);
    transition: color var(--dur-1) var(--ease);
}
.site-nav > a { border-bottom: 1px solid rgba(255, 255, 255, .08); }
.site-nav a:hover, .site-nav a.active { color: #fff; }
/* `.site-nav a` tem mais especificidade que `.btn-primary` e estava a pintar o
   texto do botão de azul-claro em vez de branco — além de feio, dava 3.95 de
   contraste sobre o vermelho. */
.site-nav .nav-cta { display: block; text-align: center; margin-top: var(--sp-4);
    border-bottom: 0; color: var(--accent-contrast); }
.site-nav .nav-cta:hover { color: var(--accent-contrast); }

.lang-switch { display: flex; gap: var(--sp-4); padding-top: var(--sp-4); }
.lang-switch a { color: var(--text-muted); font-weight: 700; font-size: var(--fs-sm); padding: 0; }
.lang-switch a.active { color: #fff; }

/* ===========================================================================
   4b. Barra utilitária
   ---------------------------------------------------------------------------
   Acima do cabeçalho e, ao contrário dele, NÃO é fixa: rola para fora e
   devolve o espaço vertical mal o visitante comece a ler. O cabeçalho encosta
   ao topo sozinho, porque é `sticky` e não `fixed`.
   =========================================================================== */
.site-topbar {
    background: var(--navy-950);

    /* Os mesmos tokens escuros que o cabeçalho declara. Sem eles, o
       --text-muted resolve para o cinzento de fundo claro e cai para 2.3 de
       contraste — foi essa a correcção feita no cabeçalho na Fase 12. */
    --text:        #b9c1dd;
    --text-strong: #ffffff;
    --text-muted:  #9ba6d1;
    --border:      rgba(255, 255, 255, .1);

    border-bottom: 1px solid var(--border);
    font-size: var(--fs-xs);
}
.site-topbar .container {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: var(--sp-2) var(--sp-5);
    padding-block: var(--sp-2);
}
.tb-left, .tb-right { display: flex; align-items: center; gap: var(--sp-5); }

.tb-item {
    display: inline-flex; align-items: center; gap: var(--sp-2);
    color: var(--text-muted); font-weight: 600;
    transition: color var(--dur-1) var(--ease);
}
.tb-item:hover { color: var(--text-strong); }
.tb-item svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* Sublinhado no livro de reclamações: é uma obrigação legal e tem de se ler
   como ligação, não como mais um rótulo da barra. */
.tb-complaints { text-decoration: underline; text-underline-offset: 3px; }

.tb-social { display: flex; align-items: center; gap: var(--sp-3); }
.tb-social a { color: var(--text-muted); transition: color var(--dur-1) var(--ease); }
.tb-social a:hover { color: var(--text-strong); }
.tb-social svg { width: 16px; height: 16px; display: block; }

@media (max-width: 900px) {
    /* O telefone sai primeiro: já existe o botão flutuante de WhatsApp e o
       número repete-se no rodapé. A morada e as reclamações ficam. */
    .tb-phone { display: none; }
    .tb-left, .tb-right { gap: var(--sp-4); }
    .tb-address {
        display: block; max-width: 46vw;
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
}

@media (prefers-reduced-motion: reduce) {
    .tb-item, .tb-social a { transition: none; }
}

/* ---------------------------------------------------------------------------
   Artigo em destaque na página inicial. Deitado, e não mais um cartão vertical:
   dentro do bloco de fecho tem de se distinguir da faixa da galeria que vem a
   seguir, senão lê-se como parte dela.
   --------------------------------------------------------------------------- */
.feat-post {
    display: grid; grid-template-columns: 1fr; gap: 0;
    background: var(--surface-raised);
    border: 1px solid var(--border); border-radius: var(--r-lg);
    overflow: hidden; margin-bottom: var(--sp-7);
    transition: transform var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
}
.feat-post:hover { transform: translateY(-4px); box-shadow: var(--sh-3); }
.feat-media { aspect-ratio: 16 / 9; overflow: hidden; background: var(--navy-800); }
.feat-media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-3) var(--ease); }
.feat-post:hover .feat-media img { transform: scale(1.04); }
.feat-body { padding: var(--sp-6); display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-3); }
.feat-body h2 { color: var(--text-strong); }
.feat-body p { color: var(--text); }
.feat-meta { color: var(--text-muted); font-size: var(--fs-sm); }
.feat-body .more { color: var(--accent-text); font-weight: 700; font-size: var(--fs-sm); }

@media (min-width: 860px) {
    .feat-post { grid-template-columns: 5fr 6fr; align-items: stretch; }
    .feat-media { aspect-ratio: auto; min-height: 100%; }
    .feat-body { padding: var(--sp-7); justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
    .feat-post, .feat-media img { transition: none; }
    .feat-post:hover { transform: none; }
    .feat-post:hover .feat-media img { transform: none; }
}

/* ===========================================================================
   5. Botões
   =========================================================================== */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
    padding: var(--sp-3) var(--sp-6);
    border: 1.5px solid transparent; border-radius: var(--r-sm);
    font-family: var(--font-body); font-weight: 700; font-size: var(--fs-base);
    letter-spacing: .01em; cursor: pointer; text-align: center;
    transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
                color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

/* --red-550 e não o vermelho da marca: com #ed1c24 o branco por cima dava
   4.38 de contraste, abaixo do mínimo para texto de 17px a negrito. */
.btn-primary { background: var(--red-550); color: #fff; }
.btn-primary:hover { background: var(--red-600); color: #fff; }

/* O ghost lia-se mal em claro (branco com borda quase invisível). Passa a
   herdar a cor do texto da superfície — funciona em claro e em escuro. */
.btn-ghost { background: transparent; color: var(--text-strong); border-color: var(--border); }
.btn-ghost:hover { border-color: var(--text-strong); }

/* ===========================================================================
   6. Hero
   =========================================================================== */
.hero-cover {
    position: relative; overflow: hidden;
    display: flex; align-items: center;
    min-height: min(88vh, 780px);
    background: var(--navy-950);
    --text: #b9c1dd; --text-strong: #fff; --text-muted: #9ba6d1; --accent-text: var(--red-400);
    --border: rgba(255,255,255,.16);
    color: var(--text);
}
/* Ordem de pintura explícita. Sem os z-index, o canvas — que o network.js
   insere como primeiro filho — ficava por baixo da fotografia e do véu, e a
   malha simplesmente não se via. */
.hero-cover .hero-bg { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; object-fit: cover; }
/* Véu em duas camadas: uma vertical, que escurece para baixo, e outra
   horizontal, que protege o lado do texto e deixa a fotografia respirar à
   direita. Foi aliviado quando entrou a aérea real do terminal — com a foto
   de stock anterior tinha de ser quase opaco. */
.hero-cover .hero-veil { position: absolute; inset: 0; z-index: 1;
    background:
        linear-gradient(180deg, rgba(7,10,24,.42) 0%, rgba(7,10,24,.62) 55%, rgba(7,10,24,.90) 100%),
        linear-gradient(90deg, rgba(7,10,24,.80) 0%, rgba(7,10,24,.55) 45%, rgba(7,10,24,.08) 100%); }
.hero-cover .mesh-canvas { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; }
.hero-cover .container { position: relative; z-index: 3; padding-block: var(--sp-8); }
/* Em rem, não em ch: `ch` mede-se na fonte do texto e dava uma coluna de
   ~190px, estreita ao ponto de partir palavras a meio.
   52rem e não mais: a coluna passa a ocupar ~73% do container e o véu ainda
   é escuro o suficiente por baixo do texto. Mais larga do que isto, o título
   entra na zona onde a fotografia já respira e o branco perde contraste. */
.hero-inner { max-width: 52rem; }
.hero-cover h1 { font-size: var(--fs-3xl); line-height: var(--lh-tight); color: #fff; margin: var(--sp-5) 0 var(--sp-4); }
.hero-cover p { color: #c6cde6; font-size: var(--fs-lg); max-width: 48ch; }
.hero-cover .kicker { color: #fff; }
.hero-cover .kicker::before { background: var(--red-500); }
.hero-cover .actions { display: flex; flex-direction: column; gap: var(--sp-3); margin-top: var(--sp-6); }

/* --- Cabeçalho de páginas internas ---------------------------------
   Era uma faixa curta com kicker + h1 + parágrafo, sem orientação nenhuma.
   Passa a ter caminho de navegação, mais altura e um remate vermelho em
   baixo, que fecha o bloco em vez de o deixar a escorrer para a secção. */
.page-hero {
    position: relative; overflow: hidden;
    background: var(--navy-900); color: #b9c1dd;
    --text-strong: #fff; --text: #b9c1dd; --text-muted: #9ba6d1; --accent-text: var(--red-400);
    --border: rgba(255,255,255,.13);
    padding-block: var(--sp-6) var(--sp-7);
    border-bottom: 3px solid var(--accent);
}
.page-hero .mesh-canvas { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; }
.page-hero .container { position: relative; z-index: 1; }
.page-hero-body { max-width: 46rem; }
.page-hero h1 { color: #fff; font-size: var(--fs-2xl); margin-top: var(--sp-4); }
/* Sem justificação nas entradas: são de uma ou duas linhas e em corpo grande,
   e a justificação tem de esticar tanto os espaços que abre buracos entre as
   palavras. O texto corrido, que tem linhas que cheguem, esse é justificado. */
.page-hero .lead { color: #c3cbe6; font-size: var(--fs-lg); margin-top: var(--sp-4);
    text-align: left; text-wrap: pretty; }
.page-meta { color: var(--text-muted); font-size: var(--fs-sm); margin-top: var(--sp-3); }

/* Caminho de navegação */
.crumbs { margin-bottom: var(--sp-6); }
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; align-items: center;
    gap: var(--sp-2); margin: 0; padding: 0; font-size: var(--fs-xs); }
.crumbs li { display: flex; align-items: center; gap: var(--sp-2); color: var(--text-muted); }
.crumbs li + li::before { content: "/"; color: rgba(255,255,255,.28); }
.crumbs a { color: var(--text-muted); transition: color var(--dur-1) var(--ease); }
.crumbs a:hover { color: #fff; }
.crumbs [aria-current] { color: #fff; font-weight: 600; }

/* ===========================================================================
   7. Superfícies — uma só linguagem de cartão
   =========================================================================== */
.card, .s-card, .hours-card, .card-form, .info-panel, .cta-panel, .surface {
    border-radius: var(--r-lg);
    border: 1px solid var(--border);
    background: var(--surface-raised);
}
.card, .hours-card, .card-form { padding: var(--sp-6); box-shadow: var(--sh-1); }
.card h3, .hours-card h3 { margin-bottom: var(--sp-3); }
.card p { color: var(--text); }
.card .more, .s-body .more { color: var(--accent-text); font-weight: 700; font-size: var(--fs-sm); }

.grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-5); }

/* Cartão de vaga aberta (carreiras). */
.vacancy-card { display: block; transition: transform var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease); }
.vacancy-card:hover { transform: translateY(-3px); box-shadow: var(--sh-2); }
.vacancy-card .meta { color: var(--text-muted); font-size: var(--fs-sm); margin-top: var(--sp-2); }
.vacancy-card .deadline { color: var(--text); font-size: var(--fs-sm); margin: var(--sp-2) 0 var(--sp-4); }

/* Cartões de serviço */
.s-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-5); }
.s-card {
    overflow: hidden; display: flex; flex-direction: column;
    box-shadow: var(--sh-1);
    transition: transform var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
}
.s-card:hover { transform: translateY(-4px); box-shadow: var(--sh-3); }
.s-media { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: var(--navy-800); }
.s-media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-3) var(--ease); }
.s-card:hover .s-media img { transform: scale(1.05); }
.s-media::after { content: ""; position: absolute; inset: 0;
    background: linear-gradient(180deg, transparent 45%, rgba(7,10,24,.55) 100%); }
.s-body { padding: var(--sp-6); display: flex; flex-direction: column; flex: 1; gap: var(--sp-3); }
.s-body h3 { margin: 0; }
.s-body p { color: var(--text); font-size: var(--fs-sm); flex: 1; }

.svc-icon { display: inline-flex; align-items: center; justify-content: center;
    width: 52px; height: 52px; border-radius: var(--r-md); margin-bottom: var(--sp-5);
    background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); }
.svc-icon svg { width: 26px; height: 26px; }

/* ===========================================================================
   8. Secção dividida, listas, passos
   =========================================================================== */
.split { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); align-items: center; }
.split .img-wrap { order: -1; }
.split img { border-radius: var(--r-lg); width: 100%; aspect-ratio: 4 / 3; object-fit: cover; box-shadow: var(--sh-2); }

/* Variante de duas fotografias empilhadas (secção do terminal). A coluna de
   texto tem seis pontos e cresce até ~670 px; uma fotografia 4:3 fica pelos
   374 px e deixava 300 px de vazio a dividir por cima e por baixo. Aqui a
   coluna estica-se e é preenchida por duas imagens de alturas diferentes.
   A segunda só entra na versão larga: em coluna única seria mais uma
   fotografia a empurrar o texto para baixo, sem ganho de composição. */
.img-stack-sec { display: none; }

/* Marcador fino em vez do círculo vermelho cheio: onze círculos em duas
   colunas eram uma parede de pontos. O cheio fica para listas curtas. */
/* Processo numerado dentro de um painel lateral. Distinta de `.steps`, que é a
   grelha grande das páginas de serviço: aqui a ordem é o conteúdo, e a lista
   tem de caber numa coluna estreita. */
.step-list { list-style: none; padding: 0; margin: var(--sp-5) 0 0; counter-reset: passo; }
.step-list li {
    position: relative; counter-increment: passo;
    padding: var(--sp-2) 0 var(--sp-2) var(--sp-6);
    color: var(--text);
}
.step-list li::before {
    content: counter(passo);
    position: absolute; left: 0; top: var(--sp-2);
    display: flex; align-items: center; justify-content: center;
    width: 1.5rem; height: 1.5rem; border-radius: var(--r-pill);
    background: var(--accent); color: var(--accent-contrast);
    font-size: var(--fs-xs); font-weight: 700; line-height: 1;
}

/* Segundo título em diante dentro de um painel: precisa de respirar do bloco
   que fecha acima dele. */
.info-panel > h3 ~ h3 { margin-top: var(--sp-6); }

.feature-list { list-style: none; padding: 0; margin: var(--sp-5) 0 0; }
.feature-list li { position: relative; padding: var(--sp-2) 0 var(--sp-2) var(--sp-6); color: var(--text); }
.feature-list li::before {
    content: ""; position: absolute; left: 0; top: 0.85em;
    width: var(--sp-4); height: 2px; background: var(--accent);
}
@media (min-width: 780px) { .feature-list.cols-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--sp-7); } }

/* Grelha — para listas longas de itens curtos (os benefícios, o impacto, a
   conformidade). Uma lista com marcadores e dez linhas espalha-se e não se lê;
   em três colunas, com filetes a separar, passa a ler-se como uma ficha
   técnica — que é o registo certo para um terminal.

   Sem numeração: estas listas são inventários, não sequências. O número fica
   reservado ao processo (`.step-list`), onde a ordem é o conteúdo. O filete
   marca o início da linha sem sugerir ordem — mesma linguagem de
   `.feature-list`. */
.benefit-grid { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: 1fr; }
.benefit-grid li {
    position: relative; font-size: var(--fs-sm);
    padding: var(--sp-4) 0 var(--sp-4) var(--sp-6);
    border-top: 1px solid var(--border);
}
.benefit-grid li::before {
    content: ""; position: absolute; left: 0; top: calc(var(--sp-4) + 0.62em);
    width: var(--sp-4); height: 2px; background: var(--accent);
}
.benefit-grid .t { color: var(--text); line-height: 1.45; }

@media (min-width: 700px) { .benefit-grid { grid-template-columns: 1fr 1fr; column-gap: var(--sp-7); } }
@media (min-width: 1050px) { .benefit-grid { grid-template-columns: repeat(3, 1fr); column-gap: var(--sp-6); } }

/* Sem numeracao visivel: por decisao do cliente os passos deixaram de abrir com
   01–04. A ordem continua a ler-se pela propria sequencia dos cartoes. */
.steps { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); }
.step { position: relative; }
.step h3 { margin-bottom: var(--sp-2); }
.step p { color: var(--text); font-size: var(--fs-sm); }

/* ===========================================================================
   9. Faixa de números
   =========================================================================== */
.stats { padding-block: var(--sp-7); border-block: 1px solid var(--border); }
.stats .grid { grid-template-columns: repeat(2, 1fr); gap: var(--sp-6) var(--sp-5); }
.stat .num {
    font-family: var(--font-head); font-weight: 700;
    font-size: var(--fs-num); line-height: 1;
    color: var(--text-strong); letter-spacing: var(--tr-tight);
}
.stat .num span, .stat .num .suf { color: var(--accent); }
.stat .lbl { color: var(--text-muted); font-size: var(--fs-sm); margin-top: var(--sp-2); }

/* ===========================================================================
   10. Painéis escuros
   =========================================================================== */
.cta-panel { padding: var(--sp-8) var(--sp-6); text-align: center; background: var(--navy-900); }
.cta-panel h2 { color: #fff; }
.cta-panel p { color: #b9c1dd; max-width: 52ch; margin: var(--sp-4) auto var(--sp-6); }

/* CTA de página inteira: em vez de um painel escuro pousado sobre branco, a
   secção toda passa a escura. Fecha a página com peso em vez de a diluir. */
.cta-final { text-align: center; }
.cta-final h2 { font-size: var(--fs-2xl); }
.cta-final p { color: var(--text); font-size: var(--fs-md); max-width: 54ch; margin: var(--sp-4) auto var(--sp-6); }

/* CTA que fecha um bloco escuro já ocupado (ex: a seguir à galeria).
   O filete separa-o do que vem acima sem precisar de outra secção. */
/* 96px no total (48 + 48). Antes eram 208px — margem de 128 mais padding de
   80 — e ficava um rasgo vazio entre a galeria e o CTA. */
.closing-cta { text-align: center; margin-top: var(--sp-7); padding-top: var(--sp-7);
    border-top: 1px solid var(--border); }
.closing-cta h2 { font-size: var(--fs-2xl); }
.closing-cta p { color: var(--text); font-size: var(--fs-md); max-width: 54ch;
    margin: var(--sp-4) auto var(--sp-6); }
/* Quando não há galeria, o filete e o recuo não fazem sentido. */
.closing-cta:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

/* Telefone e email em destaque, para quem não quer preencher formulários. */
.direct-contacts { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-3);
    font-size: var(--fs-lg); }
.direct-contacts a { color: var(--text-strong); border-bottom: 1px solid var(--accent); }
.direct-contacts a:hover { color: var(--accent); }
.direct-contacts span { color: var(--text-muted); }

.info-panel { padding: var(--sp-6); background: var(--navy-900); }
.info-panel h3 { color: #fff; margin-bottom: var(--sp-5); }
.info-panel .contact-line { display: flex; gap: var(--sp-3); margin-bottom: var(--sp-5); align-items: flex-start; font-size: var(--fs-sm); }
.info-panel .contact-line svg { width: 20px; height: 20px; flex-shrink: 0; margin-top: .2em; color: var(--accent); }
.info-panel .contact-line a { color: #dfe4f4; word-break: break-word; }
.info-panel .contact-line a:hover { color: #fff; }
.info-panel .label { display: block; font-size: var(--fs-xs); text-transform: uppercase;
    letter-spacing: var(--tr-wide); color: var(--text-muted); margin-bottom: var(--sp-1); }
.info-panel .footer-social { margin-top: var(--sp-6); }

/* ===========================================================================
   11. Formulários
   =========================================================================== */
.form { max-width: 680px; }
.form label { display: block; font-weight: 600; font-size: var(--fs-sm); margin-bottom: var(--sp-2); color: var(--text-strong); }
.form input, .form textarea, .form select {
    width: 100%; padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-5);
    border: 1px solid var(--border); border-radius: var(--r-sm);
    font-size: 16px; font-family: inherit; background: var(--surface); color: var(--text-strong);
    transition: border-color var(--dur-1) var(--ease);
}
.form input:focus, .form textarea:focus, .form select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
.form .opt { color: var(--text-muted); font-weight: 400; font-size: .85em; }
.q-row { display: grid; grid-template-columns: 1fr; gap: 0 var(--sp-5); }

/* Formulário que ocupa o cartão todo (dentro de .card-form ou .container.narrow). */
.form--wide { max-width: none; }

/* Subtítulo dentro de um formulário longo — agrupa campos por assunto. */
.form-section { margin: var(--sp-6) 0 var(--sp-5); font-size: var(--fs-md); }
.form-section:first-child { margin-top: 0; }

/* Nota de apoio por baixo de um campo ou grupo. */
.hint { color: var(--text-muted); font-size: var(--fs-sm); margin: calc(var(--sp-3) * -1) 0 var(--sp-5); }

/* Nota de rodapé de formulário — a que fica DEPOIS do botão de submissão.
   Tem de ser classe própria: o `.hint` acima leva margem superior negativa
   para se encostar ao campo que o antecede, e a seguir a um botão essa margem
   punha o texto por cima dele. */
.form-note { color: var(--text-muted); font-size: var(--fs-sm); margin: var(--sp-4) 0 0; }

/* Compromisso assumido perante o visitante — um prazo, uma garantia. Destaca-se
   do texto à volta com o filete da marca; não é mais uma linha de informação. */
.pledge {
    margin: var(--sp-5) 0 0;
    padding: var(--sp-3) 0 var(--sp-3) var(--sp-4);
    border-left: 3px solid var(--accent);
    color: var(--text-strong);
    font-weight: 600;
}

.alert { padding: var(--sp-4) var(--sp-5); border-radius: var(--r-sm); margin-bottom: var(--sp-5); }
.alert-success { background: #e7f6ec; border: 1px solid #b6e0c4; color: #1e7e44; }
.alert-error { background: #fdecea; border: 1px solid #f5c6c2; color: #c0392b; }
.alert-error ul { margin: 0; padding-left: var(--sp-5); }

.contact-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); align-items: start; }
.contact-grid .form { max-width: none; }

/* ===========================================================================
   12. Missão / visão / valores
   =========================================================================== */
.mv { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); }
.mv-item h2 { position: relative; padding-top: var(--sp-4); margin-bottom: var(--sp-3); }
.mv-item h2::before { content: ""; position: absolute; top: 0; left: 0; width: var(--sp-6); height: 2px; background: var(--accent); }
.mv-item p { color: var(--text); font-size: var(--fs-md); }

.values { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); }
.value-item .v-icon { display: block; color: var(--accent); margin-bottom: var(--sp-3); }
.value-item .v-icon svg { width: 34px; height: 34px; }
.value-item h3 { margin-bottom: var(--sp-2); }
.value-item p { color: var(--text); font-size: var(--fs-sm); max-width: 42ch; }

/* ===========================================================================
   13. Infra-estruturas, localização, horários
   =========================================================================== */
.infra-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); }
.infra-item { display: flex; gap: var(--sp-4); align-items: flex-start; }
.infra-item .i-icon { flex: 0 0 auto; width: 44px; height: 44px; border-radius: var(--r-md);
    background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent);
    display: flex; align-items: center; justify-content: center; }
.infra-item .i-icon svg { width: 22px; height: 22px; }
.infra-item h3 { font-size: var(--fs-md); margin-bottom: var(--sp-1); }
.infra-item p { color: var(--text); font-size: var(--fs-sm); }

.loc-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-7); align-items: start; }
.loc-grid h3 { margin-bottom: var(--sp-4); }

.dist-list { list-style: none; padding: 0; margin: 0; }
.dist-list li { display: flex; align-items: baseline; gap: var(--sp-4);
    padding: var(--sp-3) 0; border-bottom: 1px solid var(--border); }
.dist-list li:last-child { border-bottom: 0; }
.dist-list .km { flex: 0 0 4.5rem; font-family: var(--font-head); font-weight: 700;
    font-size: var(--fs-lg); color: var(--text-strong); }
.dist-list .km span { font-size: .6em; color: var(--text-muted); margin-left: .15em; }
.dist-list .what { flex: 1; color: var(--text); font-size: var(--fs-sm); }
.dist-list .mins { color: var(--text-muted); font-size: var(--fs-xs); white-space: nowrap; }

.hours-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-5); }
.hours-card dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: var(--sp-2) var(--sp-4); }
.hours-card dt { color: var(--text-muted); font-size: var(--fs-sm); }
.hours-card dd { margin: 0; font-weight: 600; color: var(--text-strong); font-size: var(--fs-sm); }
.hours-card .closed { margin-top: var(--sp-4); color: var(--text-muted); font-size: var(--fs-xs); }

/* ===========================================================================
   14. Equipa
   =========================================================================== */
.team-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-5); }
.team-card { text-align: center; }
.team-card .avatar { width: 100%; aspect-ratio: 1; border-radius: var(--r-pill); overflow: hidden;
    margin: 0 auto var(--sp-4); background: var(--surface-2);
    display: flex; align-items: center; justify-content: center; box-shadow: var(--sh-1); }
.team-card .avatar img { width: 100%; height: 100%; object-fit: cover; }
.team-card .avatar .ini { font-family: var(--font-head); font-size: clamp(1.5rem, 6vw, 2.25rem);
    font-weight: 700; color: var(--text-muted); }
.team-card h3 { font-size: var(--fs-md); margin-bottom: var(--sp-1); }
.team-card .role { color: var(--accent-text); font-size: var(--fs-sm); font-weight: 600; }
.team-card .bio { color: var(--text-muted); font-size: var(--fs-sm); margin-top: var(--sp-2); }

/* ===========================================================================
   15. Sub-navegação de âncoras
   =========================================================================== */
.subnav { position: sticky; top: 60px; z-index: 30;
    background: var(--navy-800); border-bottom: 1px solid rgba(255, 255, 255, .12);
    /* Navy fora do escopo escuro, tal como o cabeçalho: sem isto o
       --text-muted resolvia para o cinzento de fundo claro (3.64). */
    --text-muted: #9ba6d1; --text-strong: #ffffff; }
.subnav .container { display: flex; gap: var(--sp-6); overflow-x: auto;
    padding-block: var(--sp-3); scrollbar-width: none; }
.subnav .container::-webkit-scrollbar { display: none; }
.subnav a { white-space: nowrap; font-size: var(--fs-sm); font-weight: 600; color: var(--text-muted);
    padding-bottom: var(--sp-1); border-bottom: 2px solid transparent;
    transition: color var(--dur-1) var(--ease); }
.subnav a:hover { color: #fff; }
.subnav a.active { color: #fff; border-bottom-color: var(--accent); }
.anchor-target { scroll-margin-top: 130px; }

/* ===========================================================================
   16. Serviço — detalhe
   =========================================================================== */
/* A caixa tem a proporção com que as fotografias de serviço são construídas
   (16:10, ver scripts/build-images.php), por isso a imagem entra inteira: nada
   é cortado aqui. Era 21:9 e o `object-fit` deitava fora 31% da altura, o que
   cortava o topo das gruas, os cabeçalhos das fotos e por aí fora.

   Mantém-se uma proporção fixa (em vez de altura automática) para reservar o
   espaço antes de a imagem carregar e não haver salto no layout. O `contain`
   trata do caso das fotografias carregadas pelo backoffice, que podem vir com
   outra proporção: ficam inteiras sobre o fundo navy, em vez de recortadas. */
.svc-hero { aspect-ratio: 16 / 10; border-radius: var(--r-lg); overflow: hidden;
    background: var(--navy-800); box-shadow: var(--sh-2); margin-bottom: var(--sp-7); }
.svc-hero img { width: 100%; height: 100%; object-fit: contain; }
.svc-detail { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); }
.svc-detail h3 { margin-bottom: var(--sp-3); }

/* ===========================================================================
   16b. Artigo do blog
   =========================================================================== */
.post-cover { border-radius: var(--r-lg); box-shadow: var(--sh-2); width: 100%;
    aspect-ratio: 16 / 9; object-fit: cover; margin-bottom: var(--sp-7); }
.post-body { font-size: var(--fs-md); line-height: var(--lh-loose); }

.comment-list { margin: var(--sp-6) 0 var(--sp-7); display: grid; gap: var(--sp-4); }
.comment { background: var(--surface-raised); border: 1px solid var(--border);
    border-radius: var(--r-md); padding: var(--sp-5); }
.comment .head { display: flex; justify-content: space-between; gap: var(--sp-4);
    margin-bottom: var(--sp-2); align-items: baseline; }
.comment .who { color: var(--text-strong); font-weight: 700; }
.comment .when { color: var(--text-muted); font-size: var(--fs-xs); white-space: nowrap; }
.comment p { color: var(--text); font-size: var(--fs-sm); }

/* ===========================================================================
   17. Galeria
   =========================================================================== */
.gallery-strip { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-3); }
.g-thumb { display: block; border-radius: var(--r-md); overflow: hidden; aspect-ratio: 4 / 3; }
.g-thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-3) var(--ease); }
.g-thumb:hover img { transform: scale(1.06); }

.tabs-pill { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-6); }
.tabs-pill button { padding: var(--sp-2) var(--sp-4); border-radius: var(--r-pill);
    border: 1px solid var(--border); background: var(--surface); color: var(--text-strong);
    font-family: inherit; font-weight: 600; font-size: var(--fs-sm); cursor: pointer; }
.tabs-pill button:hover { border-color: var(--text-strong); }
.tabs-pill button.active { background: var(--navy-900); color: #fff; border-color: var(--navy-900); }

.gallery-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-4); }
.g-item { position: relative; padding: 0; border: 0; background: var(--navy-900);
    border-radius: var(--r-md); overflow: hidden; cursor: pointer; aspect-ratio: 4 / 3; }
.g-item img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-3) var(--ease); }
.g-item:hover img { transform: scale(1.05); }
.g-cat { position: absolute; left: var(--sp-3); bottom: var(--sp-3);
    background: rgba(11, 15, 38, .88); color: #fff; font-size: var(--fs-xs); font-weight: 700;
    padding: var(--sp-1) var(--sp-3); border-radius: var(--r-pill); }

.lightbox { position: fixed; inset: 0; background: rgba(7, 10, 24, .95); display: none;
    align-items: center; justify-content: center; z-index: 60; padding: var(--sp-5); }
.lightbox.open { display: flex; }
.lightbox figure { margin: 0; max-width: 1000px; max-height: 90vh; text-align: center; }
.lightbox img { max-width: 100%; max-height: 82vh; border-radius: var(--r-md); }
.lightbox figcaption { color: #dfe4f4; margin-top: var(--sp-3); font-size: var(--fs-sm); }
.lightbox-close { position: absolute; top: var(--sp-3); right: var(--sp-5); background: none;
    border: 0; color: #fff; font-size: 2.6rem; line-height: 1; cursor: pointer; }

/* ===========================================================================
   18. Rodapé
   =========================================================================== */
.site-footer { background: var(--navy-950); color: #b9c1dd; padding-block: var(--sp-8) var(--sp-6); }
.site-footer a { color: #b9c1dd; transition: color var(--dur-1) var(--ease); }
.site-footer a:hover { color: #fff; }
.site-footer .cols { display: grid; grid-template-columns: 1fr; gap: var(--sp-7); }
.site-footer .logo-box { display: inline-block; margin-bottom: var(--sp-5); }
/* `width: auto` é obrigatório: o <img> traz width="640" para reservar o espaço
   e evitar CLS, e sem isto o atributo ganha à altura e estica o logótipo. */
.site-footer .logo-box img { height: 34px; width: auto; }
.site-footer .about { font-size: var(--fs-sm); line-height: var(--lh-loose); margin-bottom: var(--sp-5); max-width: 38ch; }
.site-footer h4 { color: #fff; margin-bottom: var(--sp-4); font-size: var(--fs-sm);
    text-transform: uppercase; letter-spacing: var(--tr-wide); font-family: var(--font-body); font-weight: 700; }
.site-footer ul { list-style: none; padding: 0; margin: 0; }
.site-footer ul li { margin-bottom: var(--sp-3); font-size: var(--fs-sm); }
.site-footer .contact-line { display: flex; gap: var(--sp-3); margin-bottom: var(--sp-4);
    font-size: var(--fs-sm); align-items: flex-start; line-height: 1.5; }
.site-footer .contact-line svg { width: 17px; height: 17px; flex-shrink: 0; margin-top: .25em; color: var(--accent); }
.site-footer .copy { margin-top: var(--sp-7); padding-top: var(--sp-5);
    border-top: 1px solid rgba(255, 255, 255, .1); font-size: var(--fs-xs); color: var(--text-muted);
    display: flex; flex-direction: column; gap: var(--sp-2); }
.site-footer .copy a { text-decoration: underline; }

.footer-social { display: flex; gap: var(--sp-2); }
.footer-social a { width: 38px; height: 38px; border-radius: var(--r-sm);
    background: rgba(255, 255, 255, .07); display: flex; align-items: center; justify-content: center;
    transition: background var(--dur-1) var(--ease); }
.footer-social a:hover { background: var(--accent); }
.footer-social svg { width: 18px; height: 18px; color: #fff; }

/* ===========================================================================
   19. WhatsApp flutuante
   =========================================================================== */
.wa-float { position: fixed; right: var(--sp-4); bottom: var(--sp-4); z-index: 50;
    width: 54px; height: 54px; border-radius: var(--r-pill); background: #25d366; color: #fff;
    display: flex; align-items: center; justify-content: center; box-shadow: var(--sh-2);
    transition: transform var(--dur-1) var(--ease); }
.wa-float:hover { transform: scale(1.06); }

/* ===========================================================================
   20. Tablet — a partir de 700px
   =========================================================================== */
@media (min-width: 700px) {
    .hero-cover .actions { flex-direction: row; flex-wrap: wrap; }
    .grid, .s-grid { grid-template-columns: repeat(2, 1fr); }
    .stats .grid { grid-template-columns: repeat(4, 1fr); }
    .steps { grid-template-columns: repeat(2, 1fr); }
    .q-row { grid-template-columns: 1fr 1fr; }
    .q-row.q-row-3 { grid-template-columns: repeat(3, 1fr); }
    .site-footer .cols { grid-template-columns: 1fr 1fr; }
    .site-footer .copy { flex-direction: row; justify-content: space-between; flex-wrap: wrap; }
    .infra-grid { grid-template-columns: 1fr 1fr; gap: var(--sp-6) var(--sp-7); }
    .hours-grid { grid-template-columns: 1fr 1fr; }
    .team-grid { grid-template-columns: repeat(3, 1fr); gap: var(--sp-6); }
    .gallery-strip { grid-template-columns: repeat(3, 1fr); }
    .gallery-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 780px) {
    .mv { grid-template-columns: 1fr 1fr; gap: 0; }
    .mv-item { padding-inline: var(--sp-7); }
    .mv-item:first-child { padding-left: 0; }
    .mv-item:last-child { padding-right: 0; border-left: 1px solid var(--border); }
    .values { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: var(--sp-7) var(--sp-6); }
}

/* ===========================================================================
   21. Desktop — a partir de 980px
   =========================================================================== */
@media (min-width: 980px) {
    .container { padding-inline: var(--sp-6); }
    .split { grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
    .split--stack { align-items: stretch; }
    /* As fotografias saem do fluxo de propósito. Empilhadas normalmente, a
       altura natural das duas (635 + 374) passava a mandar na linha e era a
       coluna de texto a ficar com o vazio — o problema ao contrário. Fora do
       fluxo não contribuem para a medição: a pilha herda a altura do texto e
       reparte-a 63/37, menos os 16px de intervalo. */
    .split--stack .img-wrap { position: relative; }
    .split--stack .img-wrap img { position: absolute; left: 0; width: 100%; height: calc(63% - 8px); aspect-ratio: auto; }
    .split--stack .img-wrap img:first-child { top: 0; }
    .split--stack .img-wrap img.img-stack-sec { display: block; bottom: 0; height: calc(37% - 8px); }
    .grid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--sp-6); }
    .s-grid { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--sp-6); }
    .steps { grid-template-columns: repeat(4, 1fr); gap: var(--sp-6); }
    .contact-grid { grid-template-columns: 1.2fr .9fr; gap: var(--sp-7); }
    .loc-grid { grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
    .svc-detail { grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
    .gallery-strip { grid-template-columns: repeat(6, 1fr); }
    .gallery-grid { grid-template-columns: repeat(3, 1fr); }
    .team-grid { grid-template-columns: repeat(4, 1fr); }
    .cta-panel { padding: var(--sp-9) var(--sp-8); }
    .card-form, .info-panel { padding: var(--sp-7); }
    .site-footer .cols { grid-template-columns: 1.6fr 1fr 1fr 1.4fr; gap: var(--sp-7); }
    .infra-grid { grid-template-columns: repeat(3, 1fr); }

    /* Navegação horizontal */
    .nav-toggle { display: none; }
    .site-header .logo img { height: 38px; }
    /* `gap` em duas medidas: --sp-4 entre as ligações e --sp-5 a separar o
       bloco do botão. Com a entrada de Fornecedores a navegação passou a nove
       itens e --sp-5 em toda a linha empurrava o «Pedir cotação» para duas
       linhas em ecrãs de 1366–1560px. */
    .site-nav { display: flex; position: static; align-items: center; gap: var(--sp-4);
        padding: 0; background: none; border: 0; }
    .site-header.nav-open .site-nav { display: flex; }
    .site-nav a { display: inline; font-size: var(--fs-sm); padding: 0; border-bottom: 0; }
    .site-nav > a { border-bottom: 0; }
    /* nowrap: o rótulo do botão é duas palavras e não pode partir — partido,
       o botão cresce em altura e desalinha a linha toda. */
    .site-nav .nav-cta { display: inline-flex; margin-top: 0; white-space: nowrap;
        margin-left: var(--sp-2); padding: var(--sp-2) var(--sp-5); }
    .lang-switch { border-left: 1px solid rgba(255, 255, 255, .18); padding-left: var(--sp-4);
        padding-top: 0; gap: var(--sp-3); }
}

/* ===========================================================================
   22. Movimento
   ---------------------------------------------------------------------------
   Só `transform` e `opacity`. Tudo preso à classe `.motion`, que só existe se
   o JavaScript correr e o utilizador não pedir menos movimento — sem JS, nada
   fica escondido. Ver public/js/motion.js e o MotionAssetsTest, que falha se
   alguma regra `opacity: 0` escapar deste escopo.
   =========================================================================== */
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

.motion [data-reveal],
.motion .section-head,
.motion .split > div,
.motion .s-card,
.motion .card,
.motion .step,
.motion .value-item,
.motion .infra-item,
.motion .team-card,
.motion .hours-card,
.motion .stat,
.motion .g-thumb,
.motion .dist-list li,
.motion .cta-panel { opacity: 0; transform: translateY(14px); }

/* Classe duplicada de propósito: sobe a especificidade acima de
   `.motion .split > div` sem recorrer a !important. */
.motion .is-in.is-in {
    opacity: 1; transform: none;
    transition: opacity var(--dur-3) ease, transform var(--dur-3) var(--ease);
}

.read-progress { position: fixed; top: 0; left: 0; z-index: 60; height: 3px; width: 100%;
    background: var(--accent); transform: scaleX(0); transform-origin: 0 50%; will-change: transform; }
