/* ============================================================================
   home.css — nova homepage (portal local escuro).
   Ver _docs/plans/homepage-redesign-tema.md (P2).

   ⚠️ REGRA ABSOLUTA: TODO o selector deste ficheiro começa por `body.home`.
   Não existe tema global — o resto do site continua claro e intocado. Há um
   guard automático (.claude/skills/utilsfy_test) que FALHA se aparecer aqui um
   selector fora de `body.home`. Se precisares de estilizar algo fora da home,
   é sinal de que pertence ao style.css, não a este ficheiro.

   Carregado DEPOIS do style.css (o style.css tem o seu próprio :root na linha 1
   e ganharia por ordem de cascata se este viesse antes).
   ========================================================================== */

body.home {
    /* — superfícies — */
    --u-fundo:          #12121f;
    --u-superficie:     #1a1a2e;   /* = --cor-dark, a mesma do header/rodapé */
    --u-superficie-2:   #20203a;
    --u-superficie-elev: #262645;

    /* — texto — */
    --u-texto:          #f2f2f7;
    --u-texto-2:        #b8b8c8;
    --u-texto-3:        #8a8a9e;

    /* — bordas — */
    --u-borda:          rgba(255, 255, 255, .08);
    --u-borda-forte:    rgba(255, 255, 255, .16);

    /* — marca (não muda: é identidade) — */
    --u-acento:         #e94560;
    --u-acento-claro:   #ff6b83;   /* para TEXTO pequeno sobre escuro (contraste AA) */

    /* — forma e ritmo — */
    --u-raio-sm:  8px;
    --u-raio-md:  14px;
    --u-raio-lg:  22px;
    --u-raio-pill: 999px;
    --u-max:      1220px;
    --u-sombra-2: 0 10px 30px rgba(0, 0, 0, .35);
    --u-sombra-3: 0 24px 60px rgba(0, 0, 0, .45);

    background: var(--u-fundo);
    color: var(--u-texto);
}

/* O style.css pinta o miolo de claro; na home o fundo é escuro de ponta a ponta. */
body.home main,
body.home .container {
    background: transparent;
}

/* `main` tem max-width:1100px + padding:20px no style.css (linha 318). Na home
   isso é removido para o hero poder ser full-bleed de verdade (o padrão antigo
   `margin:-20px` só compensava o padding, não o max-width). Cada bloco passa a
   declarar a sua própria largura — os blocos legados recuperam-na já a seguir. */
body.home main {
    max-width: none;
    padding: 0;
}

/* As regras de contraste para os blocos legados do directório viveram aqui do P2
   ao P4, com a nota de que morreriam quando cada bloco fosse substituído. O P5
   substituiu os últimos ("Aberto agora", "Recentes", "Mais procuradas", "Todas
   as categorias") — já não há markup do directório na home, e as regras saíram.
   Cada bloco `u-*` declara a sua própria largura. */

/* ── Hero ─────────────────────────────────────────────────────────────────── */

body.home .u-hero {
    position: relative;
    overflow: hidden;
    background: var(--u-superficie);
    isolation: isolate;
}

body.home .u-hero-media {
    position: absolute;
    inset: 0;
    z-index: 0;
}

body.home .u-hero-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 42%;   /* mantém a linha da cidade à vista ao cortar */
    display: block;
}

/* Scrim em dois tempos: escurece o todo e adensa a esquerda, onde vive o texto.
   A foto é diurna e clara — sem isto o texto branco não tem contraste. */
body.home .u-hero-media::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
        linear-gradient(90deg, rgba(18,18,31,.94) 0%, rgba(18,18,31,.82) 42%, rgba(18,18,31,.55) 100%),
        linear-gradient(0deg,  rgba(18,18,31,.95) 0%, rgba(18,18,31,.25) 55%, rgba(18,18,31,.45) 100%);
}

body.home .u-hero-inner {
    position: relative;
    z-index: 1;
    max-width: var(--u-max);
    margin: 0 auto;
    padding: 72px 24px 84px;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: 48px;
    align-items: start;
}

body.home .u-hero-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 18px;
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--u-acento-claro);
}

body.home .u-hero-titulo {
    margin: 0 0 16px;
    font-size: clamp(2.6rem, 6vw, 4.6rem);
    line-height: 1.02;
    font-weight: 800;
    letter-spacing: -.02em;
    color: #fff;
}

body.home .u-hero-titulo span {
    display: block;
    color: var(--u-acento);
}

body.home .u-hero-tagline {
    margin: 0 0 30px;
    font-size: 1.15rem;
    color: var(--u-texto-2);
}

/* Faixa de estado sob o título (data · tempo) */
body.home .u-hero-faixa {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 0;
    background: rgba(26, 26, 46, .72);
    border: 1px solid var(--u-borda);
    border-radius: var(--u-raio-md);
    backdrop-filter: blur(6px);
    overflow: hidden;
}

body.home .u-hero-faixa-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 22px;
}

body.home .u-hero-faixa-item + .u-hero-faixa-item {
    border-left: 1px solid var(--u-borda);
}

body.home .u-hero-faixa-item i {
    font-size: 1.15rem;
    color: var(--u-acento-claro);
}

body.home .u-hero-faixa-label {
    display: block;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--u-texto-3);
}

body.home .u-hero-faixa-valor {
    display: block;
    font-size: .95rem;
    color: var(--u-texto);
}

/* Qualidade do ar: escala 1-5 da OWM (1 = melhor), do verde ao vermelho. Uma só
   variável alimenta a folha e o ponto — como no mock, em que os dois são verdes
   —, e assim num dia mau ficam os dois cor de laranja em vez de a folha continuar
   a dizer verde. A cor nunca é a única portadora do estado: o rótulo ao lado
   ("Boa", "Fraca") diz o mesmo por extenso. */
body.home .u-ar--1 { --u-ar-cor: #3ec97d; }
body.home .u-ar--2 { --u-ar-cor: #9ad14f; }
body.home .u-ar--3 { --u-ar-cor: #f2c744; }
body.home .u-ar--4 { --u-ar-cor: #f08a4b; }
body.home .u-ar--5 { --u-ar-cor: #e8556d; }

body.home .u-hero-faixa-item.u-ar i { color: var(--u-ar-cor); }

body.home .u-ar-ponto {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-left: 4px;
    border-radius: 50%;
    vertical-align: middle;
    background: var(--u-ar-cor);
}

/* ── Painel "Acessos rápidos" ─────────────────────────────────────────────── */

body.home .u-acessos {
    background: rgba(26, 26, 46, .88);
    border: 1px solid var(--u-borda);
    border-radius: var(--u-raio-lg);
    box-shadow: var(--u-sombra-3);
    backdrop-filter: blur(10px);
    padding: 22px 10px 12px;
}

body.home .u-acessos-titulo {
    margin: 0 0 8px;
    padding: 0 14px;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--u-texto);
}

body.home .u-linklist {
    list-style: none;
    margin: 0;
    padding: 0;
}

body.home .u-linklist-item a {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 12px 14px;
    border-radius: var(--u-raio-sm);
    color: var(--u-texto-2);
    text-decoration: none;
    font-size: .95rem;
    transition: background .15s ease, color .15s ease;
}

body.home .u-linklist-item + .u-linklist-item a {
    border-top: 1px solid var(--u-borda);
    border-radius: 0;
}

body.home .u-linklist-item a:hover,
body.home .u-linklist-item a:focus-visible {
    background: var(--u-superficie-elev);
    color: #fff;
}

body.home .u-linklist-item a i:first-child {
    width: 20px;
    text-align: center;
    color: var(--u-acento-claro);
}

body.home .u-linklist-seta {
    margin-left: auto;
    font-size: .8rem;
    color: var(--u-texto-3);
}

/* ── Fila de cards de estado ──────────────────────────────────────────────── */

body.home .u-cards {
    max-width: var(--u-max);
    margin: -46px auto 0;   /* sobe para encavalitar a base do hero, como no mock */
    padding: 0 24px;
    position: relative;
    z-index: 2;
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 16px;
    align-items: stretch;
}

body.home .u-card {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    /* Fundo TINGIDO com a cor da secção (não neutro): é o que dá identidade a
       cada card no mock. A tinta esvai-se na diagonal para não pesar. */
    background:
        linear-gradient(155deg, var(--u-card-tinta) 0%, rgba(0,0,0,0) 62%),
        var(--u-superficie);
    border: 1px solid var(--u-card-borda);
    border-radius: var(--u-raio-lg);
    box-shadow: var(--u-sombra-2);
    padding: 20px;
    min-height: 236px;
    /* Altura reservada ao bloco ACIMA do separador (.u-card-topo, ou o corpo
       inteiro no card do tempo). É o que põe a linha divisória à mesma altura
       nos cinco cards — sem isto cada card corta onde o seu conteúdo acaba e as
       linhas ficam em degrau. Valor = o maior bloco natural (combustíveis, 93px)
       com uma folga; ver .u-card-topo. */
    --u-card-corte: 96px;
    text-decoration: none;
    color: inherit;
    transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
}

body.home a.u-card:hover,
body.home a.u-card:focus-visible {
    transform: translateY(-3px);
    border-color: var(--u-card-cor);
    box-shadow: var(--u-sombra-3);
}

/* Ícone-marca: grande, esbatido, encostado ao canto. Dá textura ao card sem
   competir com o conteúdo. Vem no HTML (e não em ::after com \f0xx) para não
   depender dos code points do Font Awesome, que mudam entre versões. */
body.home .u-card-marca {
    position: absolute;
    right: -20px;
    top: 46px;              /* ao lado do conteúdo, não por trás do botão */
    font-size: 6rem;
    line-height: 1;
    color: var(--u-card-cor);
    opacity: .07;
    pointer-events: none;
}

/* Paleta por secção: cor sólida (ícones, bordas no hover), tinta (fundo) e
   borda em repouso. */
body.home .u-card--tempo       { --u-card-cor: #5aa2e8; --u-card-tinta: rgba(74,144,217,.20);  --u-card-borda: rgba(74,144,217,.30); }
body.home .u-card--combustivel { --u-card-cor: #3ec97d; --u-card-tinta: rgba(39,174,96,.18);   --u-card-borda: rgba(39,174,96,.28); }
body.home .u-card--farmacia    { --u-card-cor: #ff6b7a; --u-card-tinta: rgba(224,82,96,.20);   --u-card-borda: rgba(224,82,96,.32); }
body.home .u-card--eventos     { --u-card-cor: #a98bec; --u-card-tinta: rgba(142,107,212,.20); --u-card-borda: rgba(142,107,212,.32); }
/* O desporto era verde e colidia com os combustíveis — dois cards lado a lado
   com a mesma leitura. Âmbar separa-os e não pisa nenhuma das outras quatro. */
body.home .u-card--desporto    { --u-card-cor: #f0a13c; --u-card-tinta: rgba(224,140,44,.18); --u-card-borda: rgba(224,140,44,.30); }

body.home .u-card-head {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 16px;
    font-size: .715rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--u-card-cor);
    /* Não parte "Farmácia de serviço" em duas linhas — desalinhava o cabeçalho
       deste card em relação aos outros quatro. */
    white-space: nowrap;
}

body.home .u-card-head i { font-size: 1rem; }

body.home .u-card-corpo { flex: 1; position: relative; z-index: 1; }

/* Bloco acima do separador — altura mínima comum a todos os cards. */
body.home .u-card-topo { min-height: var(--u-card-corte); }

/* O card do tempo não tem .u-card-sep: o seu separador é o border-top do rodapé
   (.u-card-pe), que vem DEPOIS do corpo. Por isso é o corpo inteiro que leva o
   corte — e `flex: none`, senão o corpo esticaria até à altura da fila (a mais
   alta dos cinco) e empurraria a linha para baixo das outras. */
body.home .u-card--tempo .u-card-corpo { flex: none; min-height: var(--u-card-corte); }

/* Linha "ícone do tempo + temperatura" */
body.home .u-metrica-linha {
    display: flex;
    align-items: center;
    gap: 14px;
}

body.home .u-metrica-icone {
    font-size: 2.5rem;
    color: var(--u-card-cor);
    flex: none;
}

body.home .u-metrica-valor {
    display: block;
    font-size: 2.9rem;
    font-weight: 800;
    line-height: 1;
    color: #fff;
    letter-spacing: -.03em;
}

body.home .u-metrica-label {
    display: block;
    margin-top: 6px;
    font-size: .86rem;
    color: var(--u-texto-2);
}

/* Rótulo pequeno acima da métrica (ex.: "Gasóleo") */
body.home .u-metrica-topo {
    display: block;
    margin-bottom: 6px;
    font-size: .95rem;
    font-weight: 600;
    color: var(--u-card-cor);
}

body.home .u-metrica-unidade {
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: 0;
}

/* Botão dentro do card */
body.home .u-card-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    /* auto: empurra o botão para a base, alinhando-o entre cards de conteúdo
       com alturas diferentes. */
    margin-top: auto;
    padding: 9px 14px;
    border-radius: var(--u-raio-pill);
    background: var(--u-card-tinta);
    border: 1px solid var(--u-card-borda);
    font-size: .78rem;
    font-weight: 600;
    /* nowrap: em 5 colunas o card é estreito e "Ver todos os eventos" partia em
       duas linhas, desalinhando a base dos cards.
       stretch: com nowrap sozinho o botão ficava 11px mais largo que o espaço
       interno (176 vs 165) e era CORTADO pelo overflow:hidden do card. A esticar,
       acompanha a largura disponível seja qual for o texto ou o nº de colunas. */
    white-space: nowrap;
    color: #fff;
    align-self: stretch;
    position: relative;
    z-index: 1;
}

body.home a.u-card:hover .u-card-btn { background: var(--u-card-cor); color: #10101c; }

/* Equipas (card de futebol).
   ⚠️ As duas equipas partilham a MESMA base. O destaque (`--vencedor`) significa
   uma coisa só: ganhou este jogo. Não se aplica em empate nem em jogo por
   realizar — nesses casos não há vencedor, e destacar uma delas (por ser a da
   casa, por exemplo) afirmaria um resultado que não aconteceu. */
body.home .u-equipa {
    display: inline-block;
    padding: 4px 12px;
    border-radius: var(--u-raio-pill);
    border: 1px solid transparent;
    font-size: .84rem;
    font-weight: 600;
    color: var(--u-texto-2);
}

body.home .u-equipa--vencedor {
    background: var(--u-card-tinta);
    border-color: var(--u-card-borda);
    color: var(--u-card-cor);
}

body.home .u-card-nome {
    /* Duas linhas no máximo, com reticências: à terceira o bloco passava o
       --u-card-corte e era este card a sair do alinhamento (nomes de farmácia e
       títulos de evento são de comprimento imprevisível). */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    /* 1.18rem e não mais: a 5 colunas o card tem ~207px e nomes como "Farmácia
       Mateus" partiam em duas linhas, empurrando morada e telefone para fora. */
    font-size: 1.18rem;
    font-weight: 700;
    line-height: 1.25;
    color: #fff;
    letter-spacing: -.01em;
}

body.home .u-card-linha {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-top: 7px;
    font-size: .84rem;
    color: var(--u-texto-2);
}

body.home .u-card-linha i { margin-top: 3px; color: var(--u-card-cor); font-size: .8rem; flex: none; }

/* Uma linha só, com reticências. A morada da farmácia é o texto mais longo dos
   cinco cards: a duas linhas empurrava o fundo do card ~20px abaixo dos outros.
   Em ecrãs largos (2-3 colunas) cabe inteira; a 5 colunas corta. */
body.home .u-card-linha span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Separador interno — no mock divide o "corpo" das linhas de contacto/local. */
body.home .u-card-sep {
    height: 1px;
    margin: 14px 0 12px;
    background: var(--u-borda);
}

/* Rodapé do card: métricas secundárias (vento/humidade/chuva) */
body.home .u-card-pe {
    display: flex;
    gap: 8px;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--u-borda);
}

body.home .u-card-pe div { flex: 1; min-width: 0; }

body.home .u-card-pe strong {
    display: block;
    /* nowrap + tamanho contido: em 5 colunas o card fica estreito e "8 km/h"
       partia em duas linhas, desalinhando os rótulos uns dos outros. */
    font-size: .88rem;
    font-weight: 600;
    white-space: nowrap;
    color: var(--u-texto);
}

body.home .u-card-pe span {
    display: block;
    font-size: .7rem;
    white-space: nowrap;
    color: var(--u-texto-3);
}

/* Duelo do card de futebol: escudo em cima, nome pequeno por baixo, placar (ou
   "vs") ao meio. O escudo é o que se reconhece de relance — é ele que manda no
   card; o nome fica de apoio, para quem não identifica o emblema. */
body.home .u-duelo {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    gap: 4px;
    margin: 8px 0 4px;
}

body.home .u-duelo-lado {
    /* 1 1 0: as duas colunas ficam com a mesma largura seja qual for o nome, e o
       placar ao meio fica centrado no card. */
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
}

body.home .u-escudo {
    width: 44px;
    height: 44px;
    padding: 4px;
    border-radius: 50%;
    /* Disco claro por trás: muitos emblemas têm contornos escuros e desapareciam
       no fundo do card. */
    background: rgba(255, 255, 255, .07);
    border: 1px solid var(--u-borda);
    object-fit: contain;
    flex: none;
}

/* Equipa sem emblema (entrada manual, ex.: distritais) — o lugar mantém-se para
   as duas colunas não ficarem com alturas diferentes. */
body.home .u-escudo--vazio {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    color: var(--u-texto-3);
}

/* Dentro do duelo o nome é secundário: passa a caber em dois níveis abaixo do
   escudo, com quebra a duas linhas (a 5 colunas a coluna tem ~70px). */
body.home .u-duelo .u-equipa {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    padding: 3px 7px;
    font-size: .72rem;
    line-height: 1.25;
    text-align: center;
    overflow-wrap: anywhere;
}

/* Placar do card de futebol */
body.home .u-placar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    margin: 10px 0 4px;
    font-size: 2.5rem;
    font-weight: 800;
    line-height: 1;
    color: #fff;
    letter-spacing: -.02em;
}

/* Ao meio do duelo o placar não tem a largura toda do card: encolhe e alinha-se
   ao centro dos escudos (44px de escudo → ~14px de topo). */
body.home .u-duelo .u-placar {
    flex: none;
    gap: 5px;
    margin: 0;
    padding-top: 12px;
    font-size: 1.45rem;
}

body.home .u-placar-sep { font-size: 1.2rem; color: var(--u-texto-3); }

body.home .u-duelo .u-placar-sep { font-size: .9rem; }

body.home .u-card--desporto .u-card-corpo { text-align: center; }

/* Estado vazio — o card mantém-se na grelha em vez de desaparecer e abrir buraco. */
body.home .u-card--vazio .u-card-corpo {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    gap: 6px;
    color: var(--u-texto-3);
    font-size: .88rem;
}

body.home .u-card--vazio .u-card-corpo i { font-size: 1.5rem; opacity: .5; }

body.home .u-card-cta {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 14px;
    font-size: .85rem;
    font-weight: 600;
    color: var(--u-acento-claro);
}

/* ── Bloco duplo: destaque (carrossel) + notícias ─────────────────────────── */

body.home .u-duplo {
    max-width: var(--u-max);
    margin: 44px auto 0;
    padding: 0 24px;
    display: grid;
    /* A coluna da direita é fixa: a lista de notícias tem 3 linhas de texto curto
       e cresceria mal se acompanhasse a largura. O carrossel fica com o resto. */
    grid-template-columns: minmax(0, 1fr) 400px;
    gap: 32px;
    align-items: start;
}

body.home .u-sec { min-width: 0; }

body.home .u-sec-head {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 18px;
}

body.home .u-sec-titulo {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--u-texto);
}

/* Linha que preenche o espaço entre o título e o que estiver à direita — é o
   que dá o ar de "cabeçalho de secção" do mock sem acrescentar ornamentos. */
body.home .u-sec-head::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--u-borda);
    order: 1;
}

body.home .u-sec-head > *:not(.u-sec-titulo) { order: 2; }

body.home .u-sec-link {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: .85rem;
    font-weight: 600;
    color: var(--u-texto-2);
    text-decoration: none;
    white-space: nowrap;
}

body.home .u-sec-link:hover,
body.home .u-sec-link:focus-visible { color: var(--u-acento-claro); }

/* ── Carrossel de empresas ────────────────────────────────────────────────── */

body.home .u-carrossel-nav { display: flex; gap: 8px; }

/* ⚠️ Sem isto o atributo `hidden` do HTML não faz nada: a regra do browser
   (`[hidden]{display:none}`) perde para a regra acima, que é mais específica —
   e sem JS apareciam duas setas mortas. */
body.home .u-carrossel-nav[hidden] { display: none; }

body.home .u-carrossel-btn {
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 1px solid var(--u-borda-forte);
    background: var(--u-superficie-2);
    color: var(--u-texto-2);
    font-size: .8rem;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}

body.home .u-carrossel-btn:hover:not(:disabled),
body.home .u-carrossel-btn:focus-visible:not(:disabled) {
    background: var(--u-acento);
    border-color: var(--u-acento);
    color: #fff;
}

body.home .u-carrossel-btn:disabled { opacity: .35; cursor: default; }

body.home .u-carrossel {
    display: grid;
    grid-auto-flow: column;
    /* 4 cards à vista no desktop, como no mock; o resto rola. */
    grid-auto-columns: calc((100% - 3 * 16px) / 4);
    gap: 16px;
    overflow-x: auto;
    /* `proximity` e não `mandatory`: alinha os cards no fim do gesto sem prender
       a roda do rato no desktop, onde este contentor também rola livremente.
       ⚠️ Sem `scroll-behavior: smooth`: as setas movem o carrossel por
       `scrollLeft` directo (ver assets/js/home.js) — houve ambientes onde a
       animação de scroll não corre e o botão ficava sem efeito nenhum. */
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    /* Espaço para a sombra dos cards não ser cortada pelo overflow. */
    padding-bottom: 10px;
    scrollbar-width: none;
}

body.home .u-carrossel::-webkit-scrollbar { display: none; }

body.home .u-emp {
    scroll-snap-align: start;
    min-width: 0;
}

body.home .u-emp-link {
    display: block;
    position: relative;
    height: 100%;
    background: var(--u-superficie);
    border: 1px solid var(--u-borda);
    border-radius: var(--u-raio-md);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    box-shadow: var(--u-sombra-2);
    transition: transform .15s ease, border-color .15s ease;
}

body.home .u-emp-link:hover,
body.home .u-emp-link:focus-visible {
    transform: translateY(-3px);
    border-color: var(--u-borda-forte);
}

body.home .u-emp-media {
    display: block;
    position: relative;
    aspect-ratio: 16 / 9;
    /* Sem imagem em disco o bloco não colapsa: fica a cor da categoria. */
    background: var(--u-emp-cor, var(--u-superficie-2));
}

body.home .u-emp-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Escurece o pé da foto — é onde entra o símbolo e onde o badge tem de se ler. */
body.home .u-emp-media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(18,18,31,.10) 0%, rgba(18,18,31,.70) 100%);
}

body.home .u-badge {
    position: absolute;
    right: 10px;
    /* Centrado NA MESMA LINHA do símbolo da empresa — a base da foto —, como no
       mock: em baixo tapa muito menos a capa, que é quase sempre a foto que a
       própria empresa carregou. (Esteve no topo enquanto o texto era o comprido
       "Ficha completa", que chocava com o símbolo; com "Destaque" cabe ao lado.)
       `top:100%` + `translateY(-50%)` e não um `bottom` fixo: assim os dois
       ficam alinhados por construção, sem depender da altura de cada um. */
    top: 100%;
    transform: translateY(-50%);
    z-index: 1;
    padding: 5px 11px;
    border-radius: var(--u-raio-pill);
    font-size: .64rem;
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* Selo de ficha ACTIVA (perfil trabalhado pela empresa) — ver empresasDestaque().
   Sólido e com sombra: quem chegou aqui foi por mérito e tem de se ver, mesmo
   sobre a zona clara de uma foto. */
body.home .u-badge--destaque {
    background: var(--u-acento);
    color: #fff;
    box-shadow: 0 3px 12px rgba(0, 0, 0, .45);
}

body.home .u-emp-simbolo {
    position: absolute;
    left: 14px;
    /* Encavalitado na base da foto, como no mock — mesma âncora do selo, para
       os dois ficarem à mesma altura sem meias-alturas escritas à mão. */
    top: 100%;
    transform: translateY(-50%);
    z-index: 1;
    width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 2px solid var(--u-superficie);
    color: #fff;
    font-size: .95rem;
    overflow: hidden;
}

body.home .u-emp-simbolo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

body.home .u-emp-corpo {
    display: block;
    padding: 30px 14px 14px;
}

body.home .u-emp-nome {
    font-size: .95rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--u-texto);
    /* Nomes de empresa são longos ("Transmonvete - Clínica Veterinária,
       Unipessoal Lda.") e a coluna é estreita: 2 linhas, depois reticências. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 2.6em;
}

body.home .u-emp-cat {
    display: block;
    margin-top: 3px;
    font-size: .8rem;
    color: var(--u-texto-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

body.home .u-emp-meta {
    display: flex;
    /* flex-start e sem nowrap: "Abre amanhã às 09:00" não cabe numa linha em
       coluna estreita e era CORTADO a meio da hora. A envolver, o ícone fica
       alinhado com a primeira linha. */
    align-items: flex-start;
    gap: 6px;
    margin-top: 10px;
    font-size: .82rem;
    line-height: 1.35;
    color: var(--u-texto-2);
}

body.home .u-emp-meta i { margin-top: 2px; flex: none; }

body.home .u-emp-meta strong { color: var(--u-texto); font-weight: 700; }
body.home .u-emp-meta span   { color: var(--u-texto-3); }
body.home .u-emp-estrela     { color: #f2b544; }
body.home .u-emp-aberto      { color: #3ec97d; }
body.home .u-emp-fechado     { color: var(--u-texto-3); }

/* ── Notícias e avisos ────────────────────────────────────────────────────── */

body.home .u-feed {
    background: var(--u-superficie);
    border: 1px solid var(--u-borda);
    border-radius: var(--u-raio-md);
    overflow: hidden;
}

body.home .u-feed-item {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 16px;
    text-decoration: none;
    color: inherit;
    transition: background .15s ease;
}

body.home .u-feed-item + .u-feed-item { border-top: 1px solid var(--u-borda); }

body.home .u-feed-item:hover,
body.home .u-feed-item:focus-visible { background: var(--u-superficie-2); }

body.home .u-feed-icone {
    flex: none;
    width: 38px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--u-raio-sm);
    background: var(--u-superficie-2);
    color: var(--u-feed-cor, var(--u-texto-2));
    font-size: .95rem;
}

body.home .u-feed-corpo { flex: 1; min-width: 0; }

body.home .u-feed-fonte {
    display: block;
    margin-bottom: 3px;
    font-size: .64rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--u-feed-cor, var(--u-texto-3));
}

body.home .u-feed-titulo {
    font-size: .9rem;
    font-weight: 600;
    line-height: 1.35;
    color: var(--u-texto);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

body.home .u-feed-meta {
    display: block;
    margin-top: 4px;
    font-size: .78rem;
    color: var(--u-texto-3);
}

body.home .u-feed-idade {
    flex: none;
    padding-top: 2px;
    font-size: .75rem;
    color: var(--u-texto-3);
}

/* Aviso IPMA: a cor do nível é informação, não decoração — é a mesma escala do
   IPMA (amarelo < laranja < vermelho). */
body.home .u-feed-item--aviso .u-feed-icone {
    background: color-mix(in srgb, var(--u-feed-cor) 18%, transparent);
    color: var(--u-feed-cor);
}

body.home .u-feed-item--yellow { --u-feed-cor: #e8c34a; }
body.home .u-feed-item--orange { --u-feed-cor: #f08b3c; }
body.home .u-feed-item--red    { --u-feed-cor: #ef5a5a; }

body.home .u-feed-item--vazio .u-feed-titulo { color: var(--u-texto-2); font-weight: 500; }

/* ── Bloco de subscrição por email ────────────────────────────────────────── */
/* As classes chamam-se `u-alerta*` por razões históricas: o bloco nasceu, no P5
   da homepage, com o alerta de descida do combustível. Desde 2026-08-06 é a
   NEWSLETTER semanal (o alerta mudou-se para /combustivel/). Os nomes ficaram
   como estavam de propósito — renomear 15 selectores não muda um pixel. */

body.home .u-alerta {
    max-width: var(--u-max);
    margin: 52px auto 0;
    padding: 26px;
    display: flex;
    align-items: center;
    gap: 20px;
    flex-wrap: wrap;
    border-radius: var(--u-raio-lg);
    background:
        linear-gradient(120deg, rgba(233, 69, 96, .16) 0%, rgba(233, 69, 96, 0) 55%),
        var(--u-superficie);
    border: 1px solid rgba(233, 69, 96, .28);
}

body.home .u-alerta-icone {
    width: 52px;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--u-raio-md);
    background: rgba(233, 69, 96, .18);
    color: var(--u-acento-claro);
    font-size: 1.35rem;
    flex: none;
}

body.home .u-alerta-corpo { flex: 1 1 300px; min-width: 0; }

body.home .u-alerta-titulo {
    margin: 0 0 5px;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--u-texto);
}

body.home .u-alerta-sub {
    margin: 0;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--u-texto-2);
}

body.home .u-alerta-form {
    display: flex;
    gap: 10px;
    flex: 1 1 340px;
}

body.home .u-alerta-form input {
    flex: 1;
    min-width: 0;
    padding: 13px 16px;
    border-radius: var(--u-raio-pill);
    border: 1px solid var(--u-borda-forte);
    background: var(--u-fundo);
    color: var(--u-texto);
    font-size: .92rem;
    font-family: inherit;
}

body.home .u-alerta-form input::placeholder { color: var(--u-texto-3); }

body.home .u-alerta-form input:focus-visible {
    outline: 2px solid var(--u-acento);
    outline-offset: 1px;
}

body.home .u-alerta-form button {
    padding: 13px 22px;
    border-radius: var(--u-raio-pill);
    border: 0;
    background: var(--u-acento);
    color: #fff;
    font-size: .92rem;
    font-weight: 700;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: filter .15s ease;
}

body.home .u-alerta-form button:hover { filter: brightness(1.1); }

/* Rótulo só para leitores de ecrã — o campo tem placeholder, mas placeholder
   não é rótulo. */
body.home .u-oculto {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── Faixa de números reais ───────────────────────────────────────────────── */

/* Remate da página: uma faixa só, encostada ao rodapé, com um filete a separar.
   Não são cards — é uma linha de leitura contínua, como no mock. */
body.home .u-numeros {
    max-width: var(--u-max);
    margin: 56px auto 0;
    padding: 28px 24px 32px;
    border-top: 1px solid var(--u-borda);
}

/* O `footer` traz `margin-top:60px` do style.css, pensado para páginas que
   acabam em conteúdo solto. Aqui a faixa de números JÁ É o remate da página —
   60px + o padding da faixa abriam um buraco de mais de 100px antes do rodapé. */
body.home footer { margin-top: 0; }

body.home .u-numeros-faixa {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 26px 30px;
}

body.home .u-numero {
    display: flex;
    align-items: center;
    gap: 13px;
}

body.home .u-numero > i {
    font-size: 1.35rem;
    color: var(--u-acento);
    flex: none;
}

body.home .u-numero strong {
    display: block;
    font-size: 1.65rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: -.02em;
    color: #fff;
}

/* O rótulo carrega mais peso do que num painel de números grandes: com valores
   de 2-3 dígitos, é a frase que dá a dimensão, não o algarismo. */
body.home .u-numero span {
    display: block;
    margin-top: 5px;
    font-size: .83rem;
    color: var(--u-texto-2);
}

/* No mock esta ponta da faixa tem os ícones das redes. Aqui é o CTA: o rodapé
   logo a seguir já leva às redes e à navegação toda. */
body.home .u-numeros-cta {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 12px 20px;
    border-radius: var(--u-raio-pill);
    background: var(--u-superficie-2);
    border: 1px solid var(--u-borda-forte);
    color: var(--u-texto);
    text-decoration: none;
    font-size: .88rem;
    font-weight: 600;
    white-space: nowrap;
    transition: background .15s ease, border-color .15s ease;
}

body.home .u-numeros-cta:hover,
body.home .u-numeros-cta:focus-visible {
    background: var(--u-acento);
    border-color: var(--u-acento);
    color: #fff;
}

body.home .u-numeros-nota {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin: 22px 0 0;
    font-size: .82rem;
    color: var(--u-texto-3);
}

body.home .u-numeros-nota i { color: #3ec97d; }

/* ── Responsivo ───────────────────────────────────────────────────────────── */

@media (max-width: 1080px) {
    body.home .u-duplo {
        grid-template-columns: minmax(0, 1fr);
        gap: 36px;
    }
    /* Em coluna única a lista deixaria de ter limite de largura útil. */
    body.home .u-carrossel { grid-auto-columns: calc((100% - 2 * 16px) / 3); }
}

@media (max-width: 980px) {
    /* A faixa deixa de caber numa linha: as métricas passam a par e o CTA vai
       para baixo, a toda a largura, em vez de ficar espremido a um canto. */
    body.home .u-numero { flex: 1 1 calc(50% - 30px); }
    body.home .u-numeros-cta { flex: 1 1 100%; justify-content: center; }
}

@media (max-width: 780px) {
    body.home .u-duplo { margin-top: 32px; padding: 0 16px; }
    body.home .u-carrossel { grid-auto-columns: calc((100% - 16px) / 2); }
    body.home .u-numeros { padding-left: 16px; padding-right: 16px; }
    body.home .u-alerta { margin-left: 16px; margin-right: 16px; padding: 22px; }
}

@media (max-width: 480px) {
    body.home .u-carrossel { grid-auto-columns: 78%; }
    body.home .u-sec-titulo { font-size: 1.15rem; }
    body.home .u-numero strong { font-size: 1.45rem; }
    /* Campo por cima do botão: lado a lado, o campo ficava com ~90px. */
    body.home .u-alerta-form { flex-wrap: wrap; }
    body.home .u-alerta-form input,
    body.home .u-alerta-form button { flex: 1 1 100%; }
}


@media (max-width: 1180px) {
    /* 5 colunas deixam de caber legivelmente — 3 + 2. */
    body.home .u-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 780px) {
    body.home .u-cards {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        margin-top: 24px;
        padding: 0 16px;
    }
}

@media (max-width: 480px) {
    body.home .u-cards { grid-template-columns: minmax(0, 1fr); }
    /* Em coluna única não há linhas para alinhar entre si: o corte só abriria um
       buraco por baixo do conteúdo curto (ex.: card do tempo). */
    body.home .u-card { min-height: 0; --u-card-corte: 0; }
    /* O botão deixa de ser esticado: à largura toda do ecrã parecia um botão de
       formulário colado ao texto, e não a chamada do card. Volta a ser uma
       pastilha, com ar por cima. */
    body.home .u-card-btn {
        align-self: flex-start;
        margin-top: 16px;
        padding: 10px 18px;
    }
    body.home .u-card--desporto .u-card-btn { align-self: center; }
}

@media (max-width: 900px) {
    body.home .u-hero-inner {
        grid-template-columns: minmax(0, 1fr);
        gap: 32px;
        padding: 52px 20px 60px;
    }
    /* Em coluna única o scrim lateral deixa de fazer sentido — escurece por igual. */
    body.home .u-hero-media::after {
        background: linear-gradient(180deg, rgba(18,18,31,.88) 0%, rgba(18,18,31,.78) 55%, rgba(18,18,31,.94) 100%);
    }
}

/* A faixa passa a ocupar a largura toda e empilha, em vez de transbordar.
   ⚠️ 720px e não 560: com TRÊS itens a faixa mede ~562px (e chega a ~645px com
   "Nuvens dispersas" + "Muito fraca"), e o `flex-wrap` atirava o terceiro para
   uma segunda linha sozinho — sem separador por cima e com a primeira linha a
   acabar a meio. Empilhar cedo é melhor do que partir mal. Se algum dia entrar
   um quarto item, esta conta tem de ser refeita. */
@media (max-width: 720px) {
    body.home .u-hero-faixa { display: flex; width: 100%; }
    body.home .u-hero-faixa-item { flex: 1 1 100%; }
    body.home .u-hero-faixa-item + .u-hero-faixa-item {
        border-left: 0;
        border-top: 1px solid var(--u-borda);
    }
}

@media (max-width: 560px) {
    body.home .u-hero-inner { padding: 40px 16px 48px; }
    body.home .u-hero-tagline { font-size: 1.02rem; }
}

@media (prefers-reduced-motion: reduce) {
    body.home .u-linklist-item a { transition: none; }
    body.home .u-emp-link,
    body.home .u-feed-item,
    body.home .u-carrossel-btn { transition: none; }
}

/* ── Directório (/empresas) ── */
/* Ver _docs/plans/empresas-redesign.md. Tudo aqui sob `body.home.dir`
   (`$bodyClass = 'home dir'` em empresas.php) — a home fica em `body.home`
   sem o `.dir` e não é tocada por nada deste bloco. */

/* O style.css tem footer{margin-top:60px}, e a linha 1126 deste ficheiro pôs
   0 para a HOME acabar na faixa de números. A /empresas acaba noutro bloco
   (a sidebar ou a lista) — sem isto o rodapé colava ao último elemento. */
body.home.dir footer { margin-top: 60px; }

/* ── Barra de estado, a escuro ────────────────────────────────────────────── */
/* 🚨 Regras GENÉRICAS primeiro, EXPLÍCITAS de aviso depois — na mesma
   especificidade (0,3,1)/(0,3,2) dentro deste ficheiro, quem vem depois no
   ficheiro ganha. Sem as regras explícitas dos 3 níveis, a genérica abaixo
   pintava o pill de aviso da mesma cor do item de temperatura e o triângulo
   herdava `var(--u-acento-claro)` em vez do nível do IPMA — um aviso vermelho
   indistinguível do resto é um bug de informação, não de estética. */
body.home.dir .barra-estado {
    background: var(--u-superficie);
    border-bottom: 1px solid var(--u-borda);
}

body.home.dir .barra-item {
    color: var(--u-texto-2);
}

body.home.dir .barra-item i {
    color: var(--u-acento-claro);
}

body.home.dir .barra-item:hover {
    background: var(--u-superficie-2);
    color: var(--u-texto);
}

/* Avisos IPMA — os TRÊS níveis, explícitos. Fundos claros mantidos (contrastam
   bem sobre o fundo escuro); só a borda/hover são ajustados aqui. */
body.home.dir .barra-item--aviso-yellow {
    background: #fff3cd;
    color: #5d4d00;
    border-color: #ffc107;
}
body.home.dir .barra-item--aviso-yellow:hover {
    background: #ffe690;
    color: #5d4d00;
}
body.home.dir .barra-item--aviso-orange {
    background: #ffe0cc;
    color: #7a3d00;
    border-color: #ff9800;
}
body.home.dir .barra-item--aviso-orange:hover {
    background: #ffcc99;
    color: #7a3d00;
}
body.home.dir .barra-item--aviso-red {
    background: #ffcccc;
    color: #7a0010;
    border-color: #c73652;
}
body.home.dir .barra-item--aviso-red:hover {
    background: #ff9999;
    color: #7a0010;
}
/* Por último: o triângulo herda a cor do nível (pai), não a cor-marca dos
   outros ícones da barra. */
body.home.dir .barra-item--aviso i {
    color: inherit;
}

/* ── Hero ──────────────────────────────────────────────────────────────────
   Estrutura igual à do .u-hero (index.php) mas com classes próprias `dir-*`:
   o painel à direita é de NÚMEROS (não "Acessos rápidos") e o corpo leva a
   pesquisa, que o .u-hero não tem. */

body.home.dir .dir-hero {
    position: relative;
    overflow: hidden;
    background: var(--u-superficie);
    isolation: isolate;
}

body.home.dir .dir-hero-media {
    position: absolute;
    inset: 0;
    z-index: 0;
}

body.home.dir .dir-hero-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 42%;
    display: block;
}

body.home.dir .dir-hero-media::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
        linear-gradient(90deg, rgba(18,18,31,.94) 0%, rgba(18,18,31,.82) 42%, rgba(18,18,31,.55) 100%),
        linear-gradient(0deg,  rgba(18,18,31,.95) 0%, rgba(18,18,31,.25) 55%, rgba(18,18,31,.45) 100%);
}

/* Duas colunas (texto | números) e, por baixo, a pesquisa a atravessar ambas —
   é a composição do mock. O `align-items: end` alinha a base do bloco de texto
   com a do painel, que é mais baixo. */
body.home.dir .dir-hero-inner {
    position: relative;
    z-index: 1;
    max-width: var(--u-max);
    margin: 0 auto;
    padding: 64px 24px 48px;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 460px);
    gap: 24px 48px;
    align-items: end;
}

body.home.dir .dir-hero-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 18px;
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--u-acento-claro);
}

body.home.dir .dir-hero-titulo {
    margin: 0 0 16px;
    font-size: clamp(2.4rem, 5.4vw, 4rem);
    line-height: 1.05;
    font-weight: 800;
    letter-spacing: -.02em;
    color: #fff;
}

body.home.dir .dir-hero-titulo span {
    color: var(--u-acento-claro);
}

body.home.dir .dir-hero-tagline {
    margin: 0;
    font-size: 1.1rem;
    color: var(--u-texto-2);
}

/* ── Pesquisa do hero ─────────────────────────────────────────────────────── */

/* `grid-column: 1 / -1` — atravessa as duas colunas do .dir-hero-inner. */
body.home.dir .dir-pesquisa {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 12px;
    background: rgba(26, 26, 46, .72);
    border: 1px solid var(--u-borda-forte);
    border-radius: var(--u-raio-md);
    padding: 8px 8px 8px 20px;
    backdrop-filter: blur(6px);
}

body.home.dir .dir-pesquisa-lupa {
    flex: none;
    color: var(--u-texto-3);
    font-size: .95rem;
}

body.home.dir .dir-pesquisa input {
    flex: 1;
    min-width: 0;
    padding: 12px 14px;
    border: 0;
    background: transparent;
    color: var(--u-texto);
    font-size: .95rem;
    font-family: inherit;
}

body.home.dir .dir-pesquisa input::placeholder { color: var(--u-texto-3); }

body.home.dir .dir-pesquisa input:focus-visible {
    outline: 2px solid var(--u-acento);
    outline-offset: 2px;
    border-radius: var(--u-raio-sm);
}

body.home.dir .dir-pesquisa button {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 13px 30px;
    border: 0;
    border-radius: var(--u-raio-sm);
    background: var(--u-acento);
    color: #fff;
    font-size: .92rem;
    font-weight: 700;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: filter .15s ease;
}

body.home.dir .dir-pesquisa button:hover { filter: brightness(1.1); }

/* ── Painel de números do hero ────────────────────────────────────────────── */

/* Painel horizontal no canto superior direito, como no mock: cada mosaico é
   uma coluna (ícone / número / rótulo) e a fila reparte o espaço por igual.
   ⚠️ `grid-template-columns: repeat(auto-fit, …)` e não um número fixo: os
   mosaicos 2 e 3 têm guardas em PHP (média só com ≥20 avaliações) e o painel
   tem de continuar apresentável com 2 — ou até com 1. */
body.home.dir .dir-numeros {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
    background: rgba(26, 26, 46, .88);
    border: 1px solid var(--u-borda);
    border-radius: var(--u-raio-lg);
    box-shadow: var(--u-sombra-3);
    backdrop-filter: blur(10px);
    padding: 20px 8px;
}

body.home.dir .dir-numero-mosaico {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 10px;
    padding: 0 12px;
    min-width: 0;
}

body.home.dir .dir-numero-mosaico + .dir-numero-mosaico {
    border-left: 1px solid var(--u-borda);
}

body.home.dir .dir-numero-mosaico > i {
    flex: none;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--u-raio-md);
    background: rgba(233, 69, 96, .16);
    color: var(--u-acento-claro);
    font-size: 1.15rem;
}

body.home.dir .dir-numero-mosaico strong {
    display: block;
    font-size: 1.5rem;
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -.02em;
    color: #fff;
}

body.home.dir .dir-numero-mosaico span {
    display: block;
    margin-top: 4px;
    font-size: .76rem;
    line-height: 1.3;
    color: var(--u-texto-2);
}

/* ── "Explorar por categoria" ─────────────────────────────────────────────── */

body.home.dir .dir-cats {
    max-width: var(--u-max);
    margin: 40px auto 0;
    padding: 0 24px;
}

body.home.dir .dir-chips {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 10px;
    scrollbar-width: none;
}

body.home.dir .dir-chips::-webkit-scrollbar { display: none; }

/* Estado aberto pelo "Ver todas": a mesma fila deixa de rolar e passa a quebrar
   linha. Sem `scroll-snap-type: none` o snap continuaria a agir sobre o eixo x
   e, num contentor que já não rola, prendia o foco ao navegar por teclado. */
body.home.dir .dir-chips.dir-chips-aberto {
    flex-wrap: wrap;
    overflow-x: visible;
    scroll-snap-type: none;
}

/* O último cartão é um <button>: sem estas reposições herdava o tipo de letra
   do agente e o alinhamento centrado do .dir-chip não pegava. */
body.home.dir .dir-chip-todas {
    font: inherit;
    cursor: pointer;
    border-style: dashed;
    background: transparent;
}

body.home.dir .dir-chip-todas[hidden] { display: none; }

/* Cartão, não pílula — é a forma do mock: ícone em cima, nome, contagem por
   baixo. Largura fixa para a fila ter ritmo constante enquanto rola. */
body.home.dir .dir-chip {
    scroll-snap-align: start;
    flex: none;
    width: 142px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 8px;
    padding: 18px 10px;
    border-radius: var(--u-raio-md);
    background: var(--u-superficie);
    border: 1px solid var(--u-borda);
    color: var(--u-texto);
    text-decoration: none;
    transition: background .15s ease, border-color .15s ease, transform .15s ease;
}

body.home.dir .dir-chip:hover,
body.home.dir .dir-chip:focus-visible {
    background: var(--u-superficie-elev);
    border-color: var(--u-acento);
    transform: translateY(-2px);
}

/* Chip com o filtro ligado. O contorno de acento é o mesmo sinal do hover, mas
   permanente — e não muda a caixa (a borda já lá estava, só troca de cor), para
   a fila não saltar um pixel ao filtrar. */
body.home.dir .dir-chip-activo {
    border-color: var(--u-acento);
    background: var(--u-superficie-elev);
    box-shadow: 0 0 0 1px var(--u-acento) inset;
}

body.home.dir .dir-chip-activo .dir-chip-count { color: var(--u-texto-2); }

body.home.dir .dir-chip i {
    color: var(--u-acento-claro);
    font-size: 1.35rem;
}

/* O nome da categoria pode ter duas palavras longas ("Laboratórios de
   análises"): sem isto rebentava a largura fixa do cartão. */
body.home.dir .dir-chip-label {
    font-size: .86rem;
    font-weight: 600;
    line-height: 1.25;
    overflow-wrap: anywhere;
}

body.home.dir .dir-chip-count {
    font-size: .74rem;
    color: var(--u-texto-3);
    font-weight: 500;
}

/* ── Corpo: lista + sidebar ───────────────────────────────────────────────── */

body.home.dir .dir-corpo {
    max-width: var(--u-max);
    margin: 44px auto 0;
    padding: 0 24px;
    /* 360px e não os 400px do .u-duplo da home: aqui a coluna principal leva
       fichas horizontais de três colunas e cada píxel que a sidebar leva sai
       ao corpo da ficha, que é onde vive a descrição. */
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 32px;
    align-items: start;
}

body.home.dir .dir-lista { min-width: 0; }

/* Pílula encostada ao título, como no mock. ⚠️ O `order: 0` é obrigatório: a
   regra partilhada `body.home .u-sec-head > *:not(.u-sec-titulo) { order: 2 }`
   (home.css:696) atirava-a para depois da linha de preenchimento, ou seja para
   o extremo direito do cabeçalho — que é o lugar do "Ver todas", não o da
   contagem. */
body.home.dir .dir-lista-contagem {
    order: 0;
    flex: none;
    padding: 3px 10px;
    border-radius: var(--u-raio-pill);
    background: var(--u-superficie-2);
    border: 1px solid var(--u-borda);
    font-size: .78rem;
    font-weight: 600;
    color: var(--u-texto-2);
    white-space: nowrap;
}

/* "Ordenar por" — nasce `hidden` (só serve com JS), daí o `[hidden]` explícito
   ter de vencer o `display: flex`. */
body.home.dir .dir-lista-ordenar {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: .82rem;
    color: var(--u-texto-3);
    white-space: nowrap;
}

body.home.dir .dir-lista-ordenar[hidden] { display: none; }

body.home.dir .dir-lista-ordenar select {
    padding: 5px 10px;
    border-radius: var(--u-raio-sm);
    border: 1px solid var(--u-borda-forte);
    background: var(--u-superficie-2);
    color: var(--u-texto);
    font: inherit;
    font-size: .82rem;
    font-weight: 600;
    cursor: pointer;
}

body.home.dir .dir-lista-ordenar select:focus-visible { border-color: var(--u-acento); }

/* O menu nativo abre com o fundo do sistema; sem isto as opções saíam texto
   claro sobre branco em alguns temas do Windows. */
body.home.dir .dir-lista-ordenar option {
    background: var(--u-superficie-2);
    color: var(--u-texto);
}

/* Controlos que só existem com um filtro de categoria activo. Ambos precisam do
   `[hidden]` explícito: as regras de `display` acima são mais específicas do que
   a do agente e, sem isto, apareciam os dois no estado "todas as empresas". */
body.home.dir .dir-lista-mosaico[hidden] { display: none; }

body.home.dir .dir-lista-limpar {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border-radius: 999px;
    border: 1px solid var(--u-borda-forte);
    background: transparent;
    color: var(--u-texto-2);
    font: inherit;
    font-size: .8rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}

body.home.dir .dir-lista-limpar:hover,
body.home.dir .dir-lista-limpar:focus-visible {
    border-color: var(--u-acento);
    color: var(--u-acento-claro);
}

body.home.dir .dir-lista-limpar[hidden] { display: none; }

body.home.dir .dir-lista-vazia {
    padding: 24px;
    background: var(--u-superficie);
    border: 1px solid var(--u-borda);
    border-radius: var(--u-raio-md);
    color: var(--u-texto-2);
}

body.home.dir .dir-lista-grid {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* ── Ficha (lista principal) ──────────────────────────────────────────────── */

/* ⚠️ As três colunas medidas, não estimadas. Com 200px de foto e 210px de
   acções sobravam 256px para o corpo a 1440px — descrição e etiquetas num
   canal estreito, ao contrário do mock, onde o texto é a coluna dominante.
   150/1fr/176 (o mínimo que serve "🟡 Fecha em 24 min" e quatro botões) dá
   ~386px ao corpo com a sidebar a 360px. */
body.home.dir .dir-ficha {
    display: grid;
    grid-template-columns: 150px minmax(0, 1fr) 176px;
    gap: 18px;
    padding: 16px;
    background: var(--u-superficie);
    border: 1px solid var(--u-borda);
    border-radius: var(--u-raio-md);
    box-shadow: var(--u-sombra-2);
    /* Peso: fichas fora do ecrã inicial não pagam layout/paint até rolarem
       para perto — 153 fichas nasceram todas no HTML (§7 do plano). */
    content-visibility: auto;
    /* 180px = altura real medida das fichas (178-206px conforme o nº de linhas
       de etiquetas). Um valor muito abaixo do real faz a barra de scroll saltar
       à medida que as fichas entram em ecrã. */
    contain-intrinsic-size: 1000px 180px;
}

body.home.dir .dir-oculta { display: none; }

/* ⚠️ `width: 100%` e não um valor em píxeis: a largura da foto é a da coluna
   da grelha (.dir-ficha), e só lá. Enquanto esteve declarada nos dois sítios,
   mudar a coluna para 170px deixou a foto a 200px e ela avançou 30px por cima
   do texto do corpo — a foto tapava a primeira letra de cada nome. */
body.home.dir .dir-ficha-media {
    display: block;
    position: relative;
    width: 100%;
    height: 140px;
    border-radius: var(--u-raio-sm);
    overflow: hidden;
    background: var(--u-superficie-2);
    text-decoration: none;
}

body.home.dir .dir-ficha-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

body.home.dir .dir-ficha-media-vazio {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--dir-ficha-cor, var(--u-superficie-2));
    color: #fff;
    font-size: 1.6rem;
}

body.home.dir .dir-ficha-corpo {
    min-width: 0;
    display: flex;
    flex-direction: column;
}

body.home.dir .dir-ficha-nome-link { text-decoration: none; }

body.home.dir .dir-ficha-nome {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--u-texto);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

body.home.dir .dir-ficha-nome-link:hover .dir-ficha-nome,
body.home.dir .dir-ficha-nome-link:focus-visible .dir-ficha-nome {
    color: var(--u-acento-claro);
}

body.home.dir .dir-ficha-cat {
    display: block;
    margin-top: 3px;
    font-size: .82rem;
    color: var(--u-texto-3);
}

/* Truncagem a uma linha: as regras de overflow vivem no `span` do TEXTO, não
   no contentor flex — um `text-overflow:ellipsis` no pai flex (com o ícone
   como irmão) não corta nada, porque não há aí um único nó de texto a
   estourar. Mesmo padrão de `.u-card-linha`/`.u-card-linha span` (:499). */
body.home.dir .dir-ficha-morada {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    font-size: .82rem;
    color: var(--u-texto-2);
    min-width: 0;
}

body.home.dir .dir-ficha-morada i { color: var(--u-acento-claro); flex: none; font-size: .78rem; }

body.home.dir .dir-ficha-morada span {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

body.home.dir .dir-ficha-desc {
    margin: 8px 0 0;
    font-size: .85rem;
    line-height: 1.45;
    color: var(--u-texto-2);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

body.home.dir .dir-ficha-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}

body.home.dir .dir-ficha-tag {
    padding: 3px 10px;
    border-radius: var(--u-raio-pill);
    background: var(--u-superficie-2);
    border: 1px solid var(--u-borda);
    font-size: .72rem;
    color: var(--u-texto-2);
}

body.home.dir .dir-ficha-acoes {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: space-between;
    gap: 10px;
    text-align: right;
}

body.home.dir .dir-ficha-nota {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .86rem;
    color: var(--u-texto);
}

body.home.dir .dir-ficha-nota i { color: #f2b544; }

body.home.dir .dir-ficha-nota span { color: var(--u-texto-3); font-weight: 400; }

body.home.dir .dir-ficha-estado {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .8rem;
    font-weight: 600;
}

body.home.dir .dir-ficha-estado--normal  { color: #3ec97d; }
body.home.dir .dir-ficha-estado--urgente { color: #f2b544; }

/* Fechada: cinzento e ponto pequeno, nunca o 🟢 de rotuloAberturaEmpresa() —
   ver a guarda em empresas.php. O texto continua útil ("Abre segunda às 09:00"). */
body.home.dir .dir-ficha-estado--fechada { color: var(--u-texto-3); font-weight: 500; }
body.home.dir .dir-ficha-estado--fechada i { font-size: .5rem; opacity: .7; }

body.home.dir .dir-ficha-botoes {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: auto;
}

/* ⚠️ `position: static` é obrigatório: o `.fav-toggle` do style.css nasce
   `position:absolute; top:12px; right:12px` porque foi desenhado como overlay
   do `.cat-card` (categoria.php). Herdado tal e qual, saltava da fila de
   botões para o canto superior direito da ficha e assentava por cima do
   estado de abertura. Aqui é um botão numa fila, como os outros três. */
body.home.dir .dir-ficha-botoes .fav-toggle {
    position: static;
}

body.home.dir .dir-ficha-btn,
body.home.dir .dir-ficha-acoes .fav-toggle {
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 1px solid var(--u-borda-forte);
    background: var(--u-superficie-2);
    color: var(--u-texto-2);
    font-size: .85rem;
    text-decoration: none;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}

body.home.dir .dir-ficha-btn:hover,
body.home.dir .dir-ficha-btn:focus-visible,
body.home.dir .dir-ficha-acoes .fav-toggle:hover,
body.home.dir .dir-ficha-acoes .fav-toggle:focus-visible {
    background: var(--u-acento);
    border-color: var(--u-acento);
    color: #fff;
}

body.home.dir .dir-ficha-acoes .fav-toggle.is-fav {
    background: var(--u-acento);
    border-color: var(--u-acento);
    color: #fff;
}

/* "Ver mais empresas" */
body.home.dir .dir-mais {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    margin-top: 24px;
    padding: 14px;
    border-radius: var(--u-raio-pill);
    border: 1px solid var(--u-borda-forte);
    background: var(--u-superficie-2);
    color: var(--u-texto);
    font-size: .92rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease;
}

body.home.dir .dir-mais:hover,
body.home.dir .dir-mais:focus-visible {
    background: var(--u-acento);
    border-color: var(--u-acento);
    color: #fff;
}

/* ⚠️ Sem isto o atributo `hidden` do HTML não faz nada: a regra acima é mais
   específica que a regra do browser (`[hidden]{display:none}`) — lição do
   PR #158 (ver home.css:719, o mesmo problema no carrossel). */
body.home.dir .dir-mais[hidden] { display: none; }

/* ── Sidebar ───────────────────────────────────────────────────────────────── */

body.home.dir .dir-side {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 32px;
}

/* Cabeçalhos da sidebar: 360px não chegam para o título a 1,35rem MAIS o link
   MAIS a linha de preenchimento — "Empresas em destaque" partia em duas linhas.
   Título mais pequeno e a linha pode desaparecer se faltar espaço. */
body.home.dir .dir-side .u-sec-titulo {
    font-size: 1.12rem;
}

body.home.dir .dir-side .u-sec-head {
    gap: 12px;
    margin-bottom: 12px;
}

body.home.dir .dir-side .u-sec-head::after { min-width: 0; }

body.home.dir .dir-destaque-grid {
    display: grid;
    gap: 8px;
}

body.home.dir .dir-destaque-item {
    /* ⚠️ `relative` é o que ancora o `.u-badge` abaixo. Sem isto o selo, que
       nasce `position:absolute` no home.css:814, procuraria o ascendente
       posicionado mais próximo e aterrava fora da linha. */
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    /* ⚠️ `min-width: 0`: item de grelha nasce com `min-width: auto` e RECUSA
       encolher abaixo do seu min-content. Com o nome em `nowrap`, o min-content
       era o nome inteiro — a 390px o cartão media 443px num ecrã de 375 e punha
       a PÁGINA a rolar na horizontal. O ellipsis do nome também só funciona
       depois disto. */
    min-width: 0;
    padding: 10px 12px;
    padding-right: 92px;          /* espaço do selo, que é absoluto */
    border-radius: var(--u-raio-md);
    background: var(--u-superficie);
    border: 1px solid var(--u-borda);
    text-decoration: none;
    color: inherit;
    transition: background .15s ease, border-color .15s ease;
}

body.home.dir .dir-destaque-item:hover,
body.home.dir .dir-destaque-item:focus-visible {
    background: var(--u-superficie-2);
    border-color: var(--u-borda-forte);
}

/* O selo do `.u-emp` está ancorado à base da FOTO (`top:100%`), que aqui não
   existe: reancorado ao meio da linha. */
body.home.dir .dir-destaque-item .u-badge {
    top: 50%;
    right: 12px;
}

body.home.dir .dir-destaque-simbolo {
    flex: none;
    width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--u-raio-sm);
    color: #fff;
    font-size: .95rem;
    overflow: hidden;
}

body.home.dir .dir-destaque-simbolo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

body.home.dir .dir-destaque-corpo {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    overflow: hidden;
}

body.home.dir .dir-destaque-corpo > strong {
    font-size: .88rem;
    font-weight: 600;
    color: var(--u-texto);
    /* Uma linha só: nomes longos ("Clínica Médico Dentária - Catarina Fontes")
       partiam a linha em três e desfaziam o ritmo compacto da coluna. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

body.home.dir .dir-destaque-cat {
    font-size: .76rem;
    color: var(--u-texto-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

body.home.dir .dir-destaque-meta {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-top: 2px;
    font-size: .76rem;
    color: var(--u-texto-2);
    white-space: nowrap;
}

body.home.dir .dir-destaque-meta > i.fa-star { color: #f2b544; }

/* ── CTA "listar a empresa" ───────────────────────────────────────────────── */

body.home.dir .dir-cta {
    padding: 24px;
    border-radius: var(--u-raio-lg);
    background:
        linear-gradient(120deg, rgba(233, 69, 96, .16) 0%, rgba(233, 69, 96, 0) 55%),
        var(--u-superficie);
    border: 1px solid rgba(233, 69, 96, .28);
}

body.home.dir .dir-cta i {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-bottom: 14px;
    border-radius: var(--u-raio-md);
    background: rgba(233, 69, 96, .18);
    color: var(--u-acento-claro);
    font-size: 1.15rem;
}

body.home.dir .dir-cta h2 {
    margin: 0 0 8px;
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--u-texto);
}

body.home.dir .dir-cta p {
    margin: 0 0 18px;
    font-size: .88rem;
    line-height: 1.5;
    color: var(--u-texto-2);
}

body.home.dir .dir-cta-btn {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 12px 20px;
    border-radius: var(--u-raio-pill);
    background: var(--u-acento);
    color: #fff;
    text-decoration: none;
    font-size: .88rem;
    font-weight: 700;
    transition: filter .15s ease;
}

body.home.dir .dir-cta-btn:hover,
body.home.dir .dir-cta-btn:focus-visible { filter: brightness(1.1); }

/* ── "Aberto agora" ───────────────────────────────────────────────────────── */

body.home.dir .dir-aberto-lista {
    list-style: none;
    margin: 0;
    padding: 0;
    background: var(--u-superficie);
    border: 1px solid var(--u-borda);
    border-radius: var(--u-raio-md);
    overflow: hidden;
}

body.home.dir .dir-aberto-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 16px;
    text-decoration: none;
    color: inherit;
    transition: background .15s ease;
}

body.home.dir li + li .dir-aberto-item,
body.home.dir .dir-aberto-lista li + li {
    border-top: 1px solid var(--u-borda);
}

body.home.dir .dir-aberto-item:hover,
body.home.dir .dir-aberto-item:focus-visible { background: var(--u-superficie-2); }

body.home.dir .dir-aberto-icone {
    flex: none;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    color: #fff;
    font-size: .82rem;
}

body.home.dir .dir-aberto-corpo {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

body.home.dir .dir-aberto-corpo strong {
    font-size: .88rem;
    font-weight: 600;
    color: var(--u-texto);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

body.home.dir .dir-aberto-corpo span {
    font-size: .78rem;
    color: #3ec97d;
}

body.home.dir .dir-aberto-urgente { color: #f2b544 !important; }

/* ── Responsivo ───────────────────────────────────────────────────────────── */

/* ⚠️ 1100px e não 980px. Medido a 1024px com a sidebar ainda ao lado: a coluna
   da lista ficava com 585px e, tirados os 170px da foto, os 196px das acções e
   as goteiras, sobravam 183px para o corpo da ficha — o nome partia em três
   linhas, a morada ficava em "Av. Dom Dinis N…" e as etiquetas empilhavam uma
   por linha. O ponto de quebra tem de ser onde a FICHA deixa de caber, não onde
   a sidebar deixa de caber. */
@media (max-width: 1160px) {
    body.home.dir .dir-corpo { grid-template-columns: minmax(0, 1fr); }
}

/* Hero: colapsa a 1 coluna e ajusta o scrim NA MESMA query — o mesmo
   breakpoint do .u-hero original (home.css:1268). Separar as duas (uma a
   980px, outra a 900px) deixava uma faixa de largura com o painel de números
   já por baixo do texto mas o scrim ainda inclinado para a esquerda, como se
   ainda houvesse coluna à direita a iluminar. */
@media (max-width: 900px) {
    body.home.dir .dir-hero-inner { grid-template-columns: minmax(0, 1fr); }
    body.home.dir .dir-hero-media::after {
        background: linear-gradient(180deg, rgba(18,18,31,.88) 0%, rgba(18,18,31,.78) 55%, rgba(18,18,31,.94) 100%);
    }
}

@media (max-width: 780px) {
    body.home.dir .dir-cats,
    body.home.dir .dir-corpo { padding: 0 16px; }
    body.home.dir .dir-hero-inner { padding: 52px 16px 48px; }
}

@media (max-width: 560px) {
    body.home.dir .dir-ficha {
        grid-template-columns: minmax(0, 1fr);
    }
    body.home.dir .dir-ficha-media {
        width: 100%;
        height: 160px;
    }
    body.home.dir .dir-ficha-acoes {
        align-items: flex-start;
        text-align: left;
    }
    body.home.dir .dir-ficha-botoes { margin-top: 6px; }

    /* Três mosaicos lado a lado a esta largura dariam ~100px cada e o rótulo
       ("com contacto directo") partia-se em 4 linhas. Empilha, e o separador
       passa de vertical a horizontal. */
    body.home.dir .dir-numeros {
        grid-template-columns: minmax(0, 1fr);
        padding: 8px;
    }
    body.home.dir .dir-numero-mosaico {
        flex-direction: row;
        text-align: left;
        gap: 14px;
        padding: 14px 12px;
    }
    body.home.dir .dir-numero-mosaico + .dir-numero-mosaico {
        border-left: 0;
        border-top: 1px solid var(--u-borda);
    }

    /* A pesquisa deixa de ser uma linha: o botão passa a ocupar a largura toda
       por baixo do campo, senão sobra-lhe menos de 90px. */
    body.home.dir .dir-pesquisa {
        flex-wrap: wrap;
        padding: 10px 14px;
    }
    /* Escondida: com o input a `flex-basis: 100%` a lupa ficaria sozinha numa
       primeira linha, que é pior do que não haver lupa nenhuma. */
    body.home.dir .dir-pesquisa-lupa { display: none; }
    body.home.dir .dir-pesquisa input { flex: 1 1 100%; padding: 8px 0; }
    body.home.dir .dir-pesquisa button { flex: 1 1 100%; justify-content: center; }
}

/* ============================================================================
   mapa.php — /mapa-de-vila-real (P1). Ver _docs/plans/mapa-directorio.md.
   Mesma disciplina de escopo: tudo aqui vive sob `body.home.mapa`, para não
   arrastar a home nem o /empresas.
   ========================================================================== */

/* ── Hero ──────────────────────────────────────────────────────────────────── */
body.home.mapa .mapa-hero {
    background: var(--u-superficie);
    border-bottom: 1px solid var(--u-borda);
}

body.home.mapa .mapa-hero-inner {
    max-width: var(--u-max);
    margin: 0 auto;
    padding: 56px 24px 40px;
}

body.home.mapa .mapa-hero-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 14px;
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--u-acento-claro);
}

body.home.mapa .mapa-hero-titulo {
    margin: 0 0 10px;
    font-size: clamp(2rem, 4.4vw, 3.2rem);
    line-height: 1.08;
    font-weight: 800;
    letter-spacing: -.02em;
    color: #fff;
}

body.home.mapa .mapa-hero-titulo span { color: var(--u-acento-claro); }

body.home.mapa .mapa-hero-tagline {
    margin: 0;
    font-size: 1.05rem;
    color: var(--u-texto-2);
}

/* ── Intro editorial (feedback_seo_default: página âncora não pode ser thin
   content) ────────────────────────────────────────────────────────────────── */
body.home.mapa .mapa-intro {
    max-width: var(--u-max);
    margin: 28px auto 0;
    padding: 0 24px;
    display: grid;
    gap: 10px;
}
body.home.mapa .mapa-intro p {
    margin: 0;
    color: var(--u-texto-2);
    line-height: 1.7;
    max-width: 860px;
}
body.home.mapa .mapa-intro a { color: var(--u-acento-claro); }

/* ── Filtros ───────────────────────────────────────────────────────────────── */
body.home.mapa .mapa-filtros {
    max-width: var(--u-max);
    margin: 20px auto 0;
    padding: 14px 24px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}
body.home.mapa .mapa-filtros[hidden] { display: none; }

body.home.mapa .mapa-filtro-grupo { display: flex; gap: 8px; }

body.home.mapa .mapa-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 14px;
    border-radius: var(--u-raio-pill);
    border: 1px solid var(--u-borda-forte);
    background: var(--u-superficie-2);
    color: var(--u-texto-2);
    font: inherit;
    font-size: .85rem;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease, opacity .15s ease;
}
body.home.mapa .mapa-chip:not(.mapa-chip-activo) { opacity: .55; }
body.home.mapa .mapa-chip:hover,
body.home.mapa .mapa-chip:focus-visible { border-color: var(--u-acento); }
body.home.mapa .mapa-chip-activo {
    background: var(--u-acento);
    border-color: var(--u-acento);
    color: #fff;
    opacity: 1;
}
body.home.mapa .mapa-chip-count {
    padding: 1px 7px;
    border-radius: var(--u-raio-pill);
    background: rgba(255, 255, 255, .18);
    font-size: .72rem;
}

body.home.mapa .mapa-filtro-grupo select {
    padding: 9px 12px;
    border-radius: var(--u-raio-sm);
    border: 1px solid var(--u-borda-forte);
    background: var(--u-superficie-2);
    color: var(--u-texto);
    font: inherit;
    font-size: .85rem;
    font-weight: 600;
    cursor: pointer;
}
body.home.mapa .mapa-filtro-grupo select option {
    background: var(--u-superficie-2);
    color: var(--u-texto);
}

body.home.mapa .mapa-perto-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border-radius: var(--u-raio-pill);
    border: 1px solid var(--u-borda-forte);
    background: transparent;
    color: var(--u-texto);
    font: inherit;
    font-size: .85rem;
    font-weight: 700;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}
body.home.mapa .mapa-perto-btn:hover,
body.home.mapa .mapa-perto-btn:focus-visible { border-color: var(--u-acento); color: var(--u-acento-claro); }
body.home.mapa .mapa-perto-btn--activo { border-color: #3ea6ff; color: #3ea6ff; }

body.home.mapa .mapa-limpar {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    border-radius: var(--u-raio-pill);
    border: 1px solid var(--u-borda-forte);
    background: transparent;
    color: var(--u-texto-2);
    font: inherit;
    font-size: .8rem;
    font-weight: 600;
    cursor: pointer;
}
body.home.mapa .mapa-limpar:hover,
body.home.mapa .mapa-limpar:focus-visible { border-color: var(--u-acento); color: var(--u-acento-claro); }
body.home.mapa .mapa-limpar[hidden] { display: none; }

body.home.mapa .mapa-perto-status {
    flex-basis: 100%;
    margin: 0;
    font-size: .8rem;
    color: var(--u-texto-3);
}
body.home.mapa .mapa-perto-status[hidden] { display: none; }

/* ── Corpo: mapa + lista ───────────────────────────────────────────────────── */
body.home.mapa .mapa-corpo {
    max-width: var(--u-max);
    margin: 24px auto 60px;
    padding: 0 24px;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 400px;
    gap: 24px;
    align-items: start;
}

body.home.mapa .mapa-coluna-mapa { min-width: 0; position: sticky; top: 16px; }

/* ⚠️ A altura só existe DEPOIS de o Leaflet pegar (o JS marca `data-mapa-pronto`
   no contentor). Sem isto, quem não tem JS — ou quem apanha o `bail-out` de
   `typeof L === 'undefined'` — ficava com um rectângulo escuro de 600px vazio por
   cima da mensagem que explica porque não há mapa. Um buraco não se explica: não
   se desenha. */
body.home.mapa .mapa-canvas {
    border-radius: var(--u-raio-md);
    overflow: hidden;
}

body.home.mapa .mapa-canvas[data-mapa-pronto] {
    height: 600px;
    border: 1px solid var(--u-borda);
    background: var(--u-superficie-2);
}

/* O elemento JÁ É o `<p>` (ver mapa.php) — a regra antiga apontava a um `p`
   descendente que nunca existiu, e por isso nunca pintou nada. */
body.home.mapa .mapa-noscript {
    margin: 10px 0 0;
    padding: 12px 14px;
    border-radius: var(--u-raio-sm);
    background: var(--u-superficie-2);
    border: 1px solid var(--u-borda);
    color: var(--u-texto-2);
    font-size: .85rem;
}

body.home.mapa .mapa-contagem-area {
    margin: 10px 0 0;
    font-size: .8rem;
    font-weight: 600;
    color: var(--u-texto-3);
}
body.home.mapa .mapa-contagem-area[hidden] { display: none; }

body.home.mapa .mapa-legenda {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 14px;
    margin-top: 12px;
    padding: 12px 14px;
    border-radius: var(--u-raio-md);
    background: var(--u-superficie);
    border: 1px solid var(--u-borda);
}
body.home.mapa .mapa-legenda-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .76rem;
    color: var(--u-texto-2);
}
body.home.mapa .mapa-legenda-cor {
    width: 11px;
    height: 11px;
    border-radius: 50%;
    flex: none;
    border: 1px solid rgba(255, 255, 255, .4);
}
body.home.mapa .mapa-legenda-cor--evento {
    border-radius: 2px;
    background: #e94560;
    transform: rotate(45deg);
}

/* ── Coluna de resultados ─────────────────────────────────────────────────── */
body.home.mapa .mapa-coluna-lista { min-width: 0; }

body.home.mapa .mapa-lista-contagem {
    padding: 3px 10px;
    border-radius: var(--u-raio-pill);
    background: var(--u-superficie-2);
    border: 1px solid var(--u-borda);
    font-size: .78rem;
    font-weight: 600;
    color: var(--u-texto-2);
    white-space: nowrap;
}

body.home.mapa .mapa-lista-vazia {
    padding: 20px;
    background: var(--u-superficie);
    border: 1px solid var(--u-borda);
    border-radius: var(--u-raio-md);
    color: var(--u-texto-2);
}
body.home.mapa .mapa-lista-vazia[hidden] { display: none; }

body.home.mapa .mapa-lista-grid {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 900px;
    overflow-y: auto;
    padding-right: 4px;
}
body.home.mapa .mapa-lista-grid[hidden] { display: none; }

body.home.mapa .mapa-linha {
    border-radius: var(--u-raio-md);
    border: 1px solid var(--u-borda);
    background: var(--u-superficie);
    transition: background .15s ease, border-color .15s ease;
}
body.home.mapa .mapa-linha.mapa-oculta { display: none; }
body.home.mapa .mapa-linha--activa,
body.home.mapa .mapa-linha:hover {
    border-color: var(--u-acento);
    background: var(--u-superficie-2);
}

body.home.mapa .mapa-linha-resumo {
    display: grid;
    grid-template-columns: 38px minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
}

body.home.mapa .mapa-linha-simbolo {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: .95rem;
    flex: none;
}
body.home.mapa .mapa-linha-simbolo--evento { background: #e94560; }

body.home.mapa .mapa-linha-corpo {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

body.home.mapa .mapa-linha-nome {
    font-size: .92rem;
    font-weight: 700;
    color: var(--u-texto);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
body.home.mapa .mapa-linha-nome:hover,
body.home.mapa .mapa-linha-nome:focus-visible { color: var(--u-acento-claro); }

body.home.mapa .mapa-linha-meta {
    font-size: .78rem;
    color: var(--u-texto-3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
body.home.mapa .mapa-linha-meta i.fa-star { color: #f2b544; }

body.home.mapa .mapa-linha-semlocal {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-top: 2px;
    font-size: .72rem;
    font-weight: 600;
    color: var(--u-texto-3);
}

body.home.mapa .mapa-linha-distancia {
    margin-top: 2px;
    font-size: .72rem;
    font-weight: 700;
    color: #3ea6ff;
}
body.home.mapa .mapa-linha-distancia[hidden] { display: none; }

body.home.mapa .mapa-linha-botoes {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: none;
}
body.home.mapa .mapa-linha-btn {
    display: inline-flex;
    align-items: center;
    padding: 6px 10px;
    border-radius: var(--u-raio-sm);
    border: 1px solid var(--u-borda-forte);
    color: var(--u-texto-2);
    font-size: .74rem;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition: border-color .15s ease, color .15s ease;
}
body.home.mapa .mapa-linha-btn:hover,
body.home.mapa .mapa-linha-btn:focus-visible { border-color: var(--u-acento); color: var(--u-acento-claro); }
body.home.mapa .mapa-linha-btn--icone { padding: 6px 8px; }

/* ── Popup do Leaflet — sobrepõe o branco por omissão para o tema escuro ──── */
body.home.mapa .leaflet-popup-content-wrapper,
body.home.mapa .leaflet-popup-tip {
    background: var(--u-superficie-elev);
    color: var(--u-texto);
}
/* ⚠️ `width: auto` sozinho colapsava o popup. A `.mapa-linha-resumo` que ele
   clona é uma linha da LISTA, onde o corpo é um item flex que recebe a largura
   da coluna; dentro do popup não há nada a dar-lha e o corpo ficava com
   **largura 0** — o nome e a avaliação estavam no DOM, com o texto certo, e
   simplesmente não se viam (medido: `nomeLargura: 0`, `alturaCorpo: 115px`, o
   texto espremido). Um componente reutilizado leva as premissas do sítio onde
   nasceu; aqui a premissa em falta é "alguém me dá largura". */
body.home.mapa .leaflet-popup-content {
    margin: 10px 12px;
    width: auto !important;
    min-width: 230px;
    max-width: 300px;
}

body.home.mapa .mapa-popup .mapa-linha-corpo { min-width: 0; flex: 1 1 auto; }
body.home.mapa .mapa-popup-cab {
    margin: 0 0 6px;
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--u-texto-3);
}
/* ⚠️ No popup os botões vão para BAIXO, não para o lado. A linha da lista tem
   ~300px de coluna e cabem lado a lado; o popup tem 230-300px no total e, com os
   botões na mesma linha, sobravam 67px para o nome — "Alexandra Reis - Clínica
   Dentária" partia-se em três linhas de duas palavras. O mesmo componente, dois
   contentores de larguras muito diferentes: quem manda no arranjo é o contentor. */
body.home.mapa .mapa-popup .mapa-linha-resumo {
    padding: 6px 0;
    grid-template-columns: 32px minmax(0, 1fr);
    grid-template-areas:
        "simbolo corpo"
        "botoes  botoes";
    row-gap: 8px;
}
body.home.mapa .mapa-popup .mapa-linha-simbolo { grid-area: simbolo; }
body.home.mapa .mapa-popup .mapa-linha-corpo   { grid-area: corpo; }
body.home.mapa .mapa-popup .mapa-linha-botoes  { grid-area: botoes; justify-content: flex-start; }
body.home.mapa .mapa-popup .mapa-linha-resumo + .mapa-linha-resumo {
    border-top: 1px solid var(--u-borda);
}
body.home.mapa .mapa-popup .mapa-linha-nome,
body.home.mapa .mapa-popup .mapa-linha-meta { white-space: normal; }
body.home.mapa .leaflet-popup-close-button { color: var(--u-texto-2) !important; }

/* ── Marcadores ────────────────────────────────────────────────────────────── */
/* Losango dos eventos: <i> rotado 45°, ZERO imagens — cumpre "não marcadores
   com sprite" sem depender de circleMarker (que só sabe desenhar círculos).
   ⚠️ A rotação TEM de viver no <i> interior. O elemento de fora é do Leaflet, que
   lhe escreve `transform: translate3d(...)` INLINE a cada reposicionamento; um
   `transform` nosso na folha de estilos perde sempre para ele — medido: o
   computado ficava `matrix(1,0,0,1,…)`, sem rotação nenhuma, e saíam quadrados.
   Pela mesma razão a caixa de fora não leva `width`/`height` aqui: quem os define
   é o `iconSize` do JS, também inline. */
body.home.mapa .mapa-marker-evento-icon i {
    display: block;
    width: 100%;
    height: 100%;
    background: #e94560;
    border: 2px solid #fff;
    border-radius: 2px;
    transform: rotate(45deg);
    box-shadow: 0 1px 4px rgba(0, 0, 0, .4);
    /* Só `transform`: uma transição no elemento de FORA fazia os marcadores
       deslizarem 150ms a cada zoom, porque animava o translate do Leaflet. */
    transition: transform .15s ease;
}
body.home.mapa .mapa-marker-evento-icon--activa i { transform: rotate(45deg) scale(1.35); }

/* ── Responsivo ────────────────────────────────────────────────────────────── */
@media (max-width: 1160px) {
    body.home.mapa .mapa-corpo { grid-template-columns: minmax(0, 1fr); }
    body.home.mapa .mapa-coluna-mapa { position: static; }
    body.home.mapa .mapa-lista-grid { max-height: none; overflow-y: visible; }
}

@media (max-width: 780px) {
    body.home.mapa .mapa-hero-inner,
    body.home.mapa .mapa-intro,
    body.home.mapa .mapa-filtros,
    body.home.mapa .mapa-corpo { padding-left: 16px; padding-right: 16px; }
    body.home.mapa .mapa-canvas[data-mapa-pronto] { height: 420px; }
}

@media (max-width: 560px) {
    body.home.mapa .mapa-linha-resumo { grid-template-columns: 32px minmax(0, 1fr); }
    body.home.mapa .mapa-linha-botoes { grid-column: 1 / -1; margin-top: 6px; }
}
