/*
 * UNIAG — Design system (refresh 2026)
 *
 * Camada carregada por cima do tema Porto (Bootstrap + skins/default.css),
 * sem alterar os ficheiros vendor. A cor primária (#C8234B) é a mesma da
 * marca original — só a organização, tipografia, escala e acabamentos
 * (radius/shadow/foco) foram revistos.
 *
 * Nota de âmbito: o CSS vendor (theme.css, skins/default.css, ~25k linhas)
 * continua a usar #C8234B/#807677 em hex direto em centenas de seletores —
 * não foi reescrito para usar var(), porque o valor da cor não mudou e
 * retrofitar tudo seria alto risco por zero ganho visual. As variáveis
 * abaixo são a fonte de verdade para: esta folha, e as views Blade novas.
 *
 * CONVENÇÃO (2026-09-04): tabelas de listagem e grelhas de pessoas devem
 * ser sempre visualmente consistentes entre páginas — reaproveitar estes
 * componentes em vez de estilar caso a caso:
 *   - `.listing-sidebar`   → sidebar de navegação (tabs ou menu genérico
 *                            UNIAG), hover/active com as cores da marca.
 *   - `.listing-stats` / `.listing-stat` / `.listing-stat-icon`
 *                          → painel de estatísticas (ícone+número+label)
 *                            por baixo de tabs próprias da página (não
 *                            usar com o menu genérico UNIAG — aí não há
 *                            "estatísticas desta página" para mostrar).
 *   - `.listing-table`     → padding/vertical-align consistente em
 *                            qualquer `<table>` de listagem.
 *   - `.researcher-card` / `.researcher-card-static`
 *                          → grelha de pessoas (foto 3:4 + nome + badge/
 *                            legenda). `-static` quando o card não tem
 *                            link de destino único (ex. advisory board).
 * Ver `.pub-*` (publications) para o único exemplo de extensão
 * específica (revista/DOI/citações) — não generalizar isso, é conteúdo
 * só de publicações científicas.
 */

:root {
    /* Cor de marca — preservada */
    --primary: #C8234B;
    --primary-hover: #A81D3F;
    --primary-active: #8C1935;
    --primary-light: #F2D5DC;
    --primary-lighter: #FBEEF1;

    --secondary: #807677;
    --accent: #8C5E3C;

    --bg: #FFFFFF;
    --bg-secondary: #FAF7F7;
    --surface: #FFFFFF;

    --text-primary: #1F1B1C;
    --text-secondary: #5B5354;
    --text-muted: #8A8283;

    --border: #E7E0E1;

    --success: #2F7D4F;
    --warning: #B8842B;
    --error: #C1462B;
    --info: #3B6FA0;

    --font-display: 'Crimson Pro', Georgia, 'Times New Roman', serif;
    --font-body: 'Atkinson Hyperlegible', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 16px;

    --shadow-sm: 0 1px 2px rgba(31, 27, 28, .06), 0 1px 3px rgba(31, 27, 28, .08);
    --shadow-md: 0 4px 12px rgba(31, 27, 28, .08), 0 2px 4px rgba(31, 27, 28, .06);
    --shadow-lg: 0 12px 32px rgba(31, 27, 28, .12), 0 4px 8px rgba(31, 27, 28, .06);

    --transition-fast: 150ms ease;
    --transition-base: 250ms ease;
}

/* ==========================================================================
   Tipografia
   ========================================================================== */

html body {
    font-family: var(--font-body);
    font-size: 16px;
    line-height: 1.7;
    color: var(--text-primary);
}

h1, h2, h3, h4, h5, h6,
.font-display {
    font-family: var(--font-display);
    color: var(--text-primary);
    letter-spacing: -0.01em;
}

h1 { font-weight: 700; font-size: 2.25rem; line-height: 1.2; }
h2 { font-weight: 600; font-size: 1.75rem; line-height: 1.25; }
h3 { font-weight: 600; font-size: 1.375rem; line-height: 1.3; }
h4 { font-weight: 600; font-size: 1.125rem; line-height: 1.35; }

p, li, td, th, label,
.text-color-dark, .thumb-info-caption-text {
    color: var(--text-primary);
}

small, .text-muted, .thumb-info-type {
    color: var(--text-muted) !important;
}

html a {
    color: var(--primary);
    transition: color var(--transition-fast);
}

html a:hover {
    color: var(--primary-hover);
}

/* ==========================================================================
   Botões
   ========================================================================== */

html .btn {
    border-radius: var(--radius-md);
    font-weight: 600;
    letter-spacing: .01em;
    transition: background-color var(--transition-base), border-color var(--transition-base),
        box-shadow var(--transition-base), transform var(--transition-base);
}

html .btn-primary {
    background-color: var(--primary);
    border-color: var(--primary);
    color: #fff;
    box-shadow: var(--shadow-sm);
}

html .btn-primary:hover,
html .btn-primary.hover {
    background-color: var(--primary-hover);
    border-color: var(--primary-hover);
    color: #fff;
    box-shadow: var(--shadow-md);
    transform: translateY(-1px);
}

html .btn-primary:active {
    background-color: var(--primary-active);
    border-color: var(--primary-active);
    transform: translateY(0);
}

html .btn-primary:focus,
html .btn-primary.focus {
    box-shadow: 0 0 0 3px rgba(200, 35, 75, .35);
}

html .btn-primary:disabled,
html .btn-primary.disabled {
    opacity: .55;
    box-shadow: none;
    transform: none;
}

html .btn-outline-primary {
    color: var(--primary);
    border-color: var(--primary);
}

html .btn-outline-primary:hover {
    background-color: var(--primary);
    border-color: var(--primary);
    box-shadow: var(--shadow-sm);
}

/* ==========================================================================
   Cards / featured-box / thumb-info (usados em partners, advisory,
   researchers, secretariat, uniag...)
   ========================================================================== */

.featured-box .box-content,
.thumb-info,
.grid-view,
.post,
.card {
    border-radius: var(--radius-md);
}

.featured-box.featured-box-effect-4 .box-content {
    box-shadow: var(--shadow-sm);
    transition: box-shadow var(--transition-base), transform var(--transition-base);
}

.featured-box.featured-box-effect-4:hover .box-content {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.featured-box h4 {
    color: var(--text-primary);
    font-size: 1rem;
}

.thumb-info-wrapper img {
    border-radius: var(--radius-md);
}

/* ==========================================================================
   .section-angled-content (homepage) — não tem nenhum CSS no tema vendor,
   incluindo position/z-index. Como o `.particles-wrapper` irmão é absolute
   + z-index:1 (cobre a secção toda), sem isto o conteúdo real fica por
   baixo da camada de partículas e os cliques em botões/links são
   intercetados por ela mesmo sendo visualmente transparente.
   ========================================================================== */

.section-angled-content {
    position: relative;
    z-index: 2;
}

/* ==========================================================================
   Keywords (homepage) — sem card/borda, ícone em círculo tintado
   ========================================================================== */

.keywords-grid {
    row-gap: 2.5rem;
}

.keyword-item {
    text-align: center;
    padding: 0 1rem;
}

.keyword-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 96px;
    height: 96px;
    margin: 0 auto 1.5rem;
    border-radius: 50%;
    background-color: var(--primary-lighter);
    transition: background-color var(--transition-base), transform var(--transition-base);
}

.keyword-icon i {
    font-size: 2.75rem;
    color: var(--primary);
}

.keyword-item:hover .keyword-icon {
    background-color: var(--primary-light);
    transform: translateY(-3px);
}

.keyword-item h4 {
    font-family: var(--font-body);
    font-size: 0.8rem;
    font-weight: 400;
    color: var(--text-secondary);
    margin: 0;
    letter-spacing: 0.01em;
}

/* ==========================================================================
   Counters (homepage, "Scientific Outcomes") — mesma linguagem de ícone
   em círculo do Keywords, retintada para o fundo crimson desta secção.
   ========================================================================== */

.counter-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    margin: 0 auto 1rem;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, .15);
    transition: background-color var(--transition-base), transform var(--transition-base);
}

.counter-icon i {
    font-size: 2rem;
    color: #fff;
}

.counter-primary:hover .counter-icon {
    background-color: rgba(255, 255, 255, .25);
}

.counter-primary a {
    display: inline-block;
    transition: transform var(--transition-base);
}

.counter-primary:hover a {
    transform: translateY(-3px);
}

/* ==========================================================================
   Tabelas (publicações, prémios, newsletters, projetos...)
   ========================================================================== */

.table {
    border-color: var(--border);
    color: var(--text-primary);
}

.table thead th {
    color: var(--text-secondary);
    font-weight: 600;
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    border-bottom-width: 2px;
    border-color: var(--border);
    vertical-align: middle;
}

.table td, .table th {
    border-color: var(--border);
}

.table-striped tbody tr:nth-of-type(odd) {
    background-color: var(--bg-secondary);
}

.table tbody tr:hover {
    background-color: var(--primary-lighter);
}

.grid-view .summary {
    color: var(--text-muted);
    font-size: .875rem;
    margin-bottom: .75rem;
}

.pagination .page-link {
    color: var(--primary);
    border-color: var(--border);
    border-radius: var(--radius-sm);
}

.pagination .page-item.active .page-link {
    background-color: var(--primary);
    border-color: var(--primary);
    color: #fff;
}

/* ==========================================================================
   Sidebar de tabs + painel de stats — componente partilhado por páginas de
   listagem com abas próprias (publications, investigation): sidebar com
   nav-list a trocar entre sub-vistas da mesma tabela, e um pequeno painel
   de estatísticas (ícone+número+label) por baixo. Não usar em páginas cuja
   sidebar é o menu genérico "UNIAG" (regulations, visiting, etc.) — aí a
   sidebar não representa abas desta página.
   ========================================================================== */

.listing-sidebar .nav-link {
    color: var(--text-secondary);
    border-radius: var(--radius-sm);
    padding: .5rem .75rem .5rem 1.75rem;
    transition: background-color var(--transition-fast), color var(--transition-fast);
}

.listing-sidebar .nav-link:hover {
    color: var(--primary);
    background-color: var(--primary-lighter);
}

.listing-sidebar .nav-link.active {
    color: var(--primary-active);
    background-color: var(--primary-light);
    font-weight: 600;
}

.listing-stats {
    display: flex;
    flex-direction: column;
    gap: .9rem;
    margin-top: -1rem;
    padding: 1.25rem;
    background-color: var(--bg-secondary);
    border-radius: var(--radius-md);
}

.listing-stat {
    display: flex;
    align-items: center;
    gap: .85rem;
}

.listing-stat + .listing-stat {
    padding-top: .9rem;
    border-top: 1px solid var(--border);
}

.listing-stat-icon {
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background-color: var(--primary-lighter);
    color: var(--primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
}

.listing-stat strong {
    display: block;
    font-family: var(--font-display);
    font-size: 1.375rem;
    color: var(--text-primary);
    line-height: 1.15;
}

.listing-stat span {
    color: var(--text-muted);
    font-size: .6875rem;
    text-transform: uppercase;
    letter-spacing: .04em;
}

/* Polish genérico para tabelas de listagem simples (visiting, etc.) — sem
   os campos específicos de publicações (revista/DOI/citações), só melhor
   alinhamento/espaçamento/hierarquia. */
.listing-table td {
    vertical-align: middle;
    padding-top: .85rem;
    padding-bottom: .85rem;
}

/* ==========================================================================
   News / Events (/site/news) — grelha editorial, substitui o .post/.blog-posts
   genérico do tema.
   ========================================================================== */

.news-filters {
    padding: 1.25rem 1.5rem;
    background-color: var(--bg-secondary);
    border-radius: var(--radius-md);
}

.news-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: box-shadow var(--transition-base), transform var(--transition-base), border-color var(--transition-base);
}

.news-card:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-3px);
    border-color: var(--primary-light);
}

.news-card-image {
    position: relative;
    display: block;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background-color: var(--bg-secondary);
}

.news-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--transition-base);
}

.news-card:hover .news-card-image img {
    transform: scale(1.05);
}

/* A imagem do cartão aparece sempre inteira, sobre a própria imagem
   desfocada — ver x-news-card-image. */
.news-card-image.is-contained { isolation: isolate; }

.news-card-image.is-contained img { object-fit: contain; }

.news-card-backdrop {
    position: absolute;
    inset: -20px;
    z-index: -1;
    background-position: center;
    background-size: cover;
    filter: blur(18px) saturate(1.15);
    opacity: .55;
}

/* Inteira, a imagem não precisa do zoom do hover para parecer viva, e o
   zoom cortava-lhe as margens. */
.news-card:hover .news-card-image.is-contained img { transform: none; }

.news-card-date { z-index: 1; }

.news-card-date {
    position: absolute;
    left: .85rem;
    bottom: .85rem;
    background-color: rgba(255, 255, 255, .95);
    color: var(--text-primary);
    font-size: .6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    padding: .3rem .65rem;
    border-radius: var(--radius-sm);
}

.news-card-body {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: 1.25rem 1.4rem 1.5rem;
}

.news-card-title {
    font-family: var(--font-display);
    font-size: 1.125rem;
    font-weight: 600;
    line-height: 1.35;
    margin: 0 0 .6rem;
}

.news-card-title a {
    color: var(--text-primary);
    text-decoration: none;
}

.news-card-title a:hover {
    color: var(--primary);
}

.news-card-excerpt {
    flex: 1;
    color: var(--text-secondary);
    font-size: .875rem;
    line-height: 1.6;
    margin: 0 0 1rem;
}

.news-card-link {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    color: var(--primary);
    font-weight: 700;
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    text-decoration: none;
}

.news-card-link:hover {
    color: var(--primary-hover);
    text-decoration: none;
}

.news-card-link i {
    font-size: .75em;
    transition: transform var(--transition-fast);
}

.news-card:hover .news-card-link i {
    transform: translateX(3px);
}

/* News detail (/news/{slug}) — o .page-header do tema tem sempre fundo
   escuro (#807677, ver theme.css) e só trata a cor do <h1> (branco); estes
   elementos extra precisam das suas próprias cores claras, não das
   variáveis de texto pensadas para fundo branco (--text-muted, etc.). */

.page-header-breadcrumb {
    color: rgba(255, 255, 255, .65);
    font-size: .875rem;
}

.page-header-breadcrumb a {
    color: rgba(255, 255, 255, .9);
}

.page-header-breadcrumb a:hover {
    color: #fff;
}

.page-header-meta {
    color: rgba(255, 255, 255, .8);
}

/* ==========================================================================
   Partners (/site/partners) — mapa + grelha de logos (110 instituições),
   substitui o .featured-box genérico do tema por um card de logo uniforme
   com pesquisa client-side (lista demasiado grande para não ter filtro).
   ========================================================================== */

.partners-map {
    padding: .75rem;
    background-color: var(--bg-secondary);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

/* Barra de pesquisa client-side reutilizável (partners, links, ...) — nota:
   .partners-search nunca tinha CSS próprio, só espaçamento do Bootstrap;
   generalizado aqui para .search-toolbar e reaproveitado nas duas páginas. */
.search-toolbar {
    padding: 1rem 1.25rem;
    background-color: var(--bg-secondary);
    border-radius: var(--radius-md);
}

/* ==========================================================================
   Contact (/contacts) — única página do site sem page-header (corrigido) e
   com um painel de contactos/mapa a condizer com o resto do design system.
   ========================================================================== */

.contact-info-card {
    padding: 1.75rem;
    background-color: var(--bg-secondary);
    border-radius: var(--radius-lg);
}

.contact-map {
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
}

.partner-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
    padding: 1.5rem 1rem;
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    text-align: center;
    text-decoration: none;
    transition: box-shadow var(--transition-base), transform var(--transition-base), border-color var(--transition-base);
}

.partner-card:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-3px);
    border-color: var(--primary-light);
    text-decoration: none;
}

.partner-card-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 72px;
    margin-bottom: 1rem;
}

.partner-card-logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.partner-card-name {
    margin: 0;
    color: var(--text-primary);
    font-size: .8125rem;
    font-weight: 600;
    line-height: 1.4;
}

/* A tooltip do jsVectorMap não é controlada pela option "tooltip.style" da
   config JS (é ignorada por esta versão da lib) — o estilo real vem da
   classe .jvm-tooltip, definida no CSS do próprio plugin (fundo
   azul/indigo por default). !important porque estamos a sobrepor um
   componente de terceiros que pode aplicar cor inline via JS. */
.jvm-tooltip {
    background-color: var(--text-primary) !important;
    color: #fff !important;
    border: none !important;
    border-radius: var(--radius-sm) !important;
    padding: .5rem .85rem !important;
    font-family: var(--font-body) !important;
    font-size: .8125rem !important;
    box-shadow: var(--shadow-md) !important;
}

/* Notícia: imagem e texto lado a lado a partir de 992px, empilhados abaixo.
   A coluna da imagem é um pouco mais estreita que a do texto. */
.news-detail {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 2rem;
    /* A largura útil do .container do cabeçalho (1140 - 2×15): a imagem
       alinha com o início do título. */
    max-width: 1110px;
    margin: 0 auto;
}

@media (min-width: 992px) {
    .news-detail {
        grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
        gap: 3.5rem;
        align-items: start;
    }

    /* Com texto mais longo que a imagem, a imagem acompanha a leitura. */
    .news-detail-media {
        position: sticky;
        top: 7rem;
    }
}

.news-detail--no-media { max-width: 75ch; }

.news-detail-media { margin: 0; }

/* Moldura fixa: o espaço fica reservado antes de a imagem carregar, e todas
   as notícias têm a mesma forma, seja a fotografia retrato, quadrada ou um
   banner. */
.news-detail-frame {
    position: relative;
    display: block;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    border-radius: var(--radius-lg);
    background: var(--bg-secondary);
    box-shadow: var(--shadow-sm);
    isolation: isolate;
}

.news-detail-backdrop {
    position: absolute;
    inset: -24px;
    z-index: -1;
    background-position: center;
    background-size: cover;
    filter: blur(22px) saturate(1.15);
    opacity: .55;
}

.news-detail-frame img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    transition: transform .3s ease;
}

.news-detail-zoom {
    position: absolute;
    right: .75rem;
    bottom: .75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .92);
    color: var(--text-primary);
    font-size: .875rem;
    box-shadow: var(--shadow-sm);
    opacity: 0;
    transition: opacity .2s ease;
}

.news-detail-frame:hover img { transform: scale(1.015); }
.news-detail-frame:hover .news-detail-zoom,
.news-detail-frame:focus-visible .news-detail-zoom { opacity: 1; }
.news-detail-frame:focus-visible { outline: 3px solid var(--primary); outline-offset: 3px; }

/* Em ecrã tátil não há hover: o ícone fica sempre à vista. */
@media (hover: none) {
    .news-detail-zoom { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .news-detail-frame img, .news-detail-zoom { transition: none; }
    .news-detail-frame:hover img { transform: none; }
}

/* Lightbox da notícia: a imagem inteira por cima da página. */
.news-lightbox {
    max-width: none;
    max-height: none;
    margin: auto;
    padding: 0;
    border: 0;
    background: transparent;
    overflow: visible;
}

.news-lightbox::backdrop { background: rgba(20, 16, 17, .88); }

.news-lightbox[open] { animation: news-lightbox-in .2s ease-out; }

@keyframes news-lightbox-in {
    from { opacity: 0; transform: scale(.97); }
    to { opacity: 1; transform: none; }
}

.news-lightbox img {
    display: block;
    max-width: 94vw;
    max-height: 90vh;
    max-height: 90dvh;
    border-radius: var(--radius-md);
    box-shadow: 0 20px 60px -20px rgba(0, 0, 0, .6);
}

.news-lightbox-close {
    position: fixed;
    top: 1rem;
    right: 1rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: 999px;
    background: rgba(255, 255, 255, .95);
    color: var(--text-primary);
    font-size: 1.125rem;
    cursor: pointer;
}

.news-lightbox-close:hover { background: #fff; color: var(--primary); }
.news-lightbox-close:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }

/* A página por baixo não se mexe enquanto a imagem está aberta. */
html:has(.news-lightbox[open]) { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
    .news-lightbox[open] { animation: none; }
}

.news-detail-content { min-width: 0; }

.news-detail-back { margin: 2.5rem 0 0; }

.news-detail-body {
    max-width: 65ch;
    color: var(--text-primary);
    font-size: 1.0625rem;
    line-height: 1.75;
}

.news-detail--no-media .news-detail-body { margin: 0 auto; }

/* O primeiro parágrafo é quase sempre o resumo da notícia: começa colado ao
   topo da imagem, sem a margem do tema. */
.news-detail-body > :first-child { margin-top: 0; }

.news-detail-body p {
    margin-bottom: 1.25rem;
}

.news-detail-body a {
    color: var(--primary);
}

.news-detail-body img {
    max-width: 100%;
    height: auto;
    border-radius: var(--radius-md);
}

/* ==========================================================================
   Researcher cards (/site/researchers) — grelha de cards clean, substitui
   o thumb-info genérico do tema (foto 200x300 fixa + email como subtítulo).
   ========================================================================== */

.researcher-type-filters {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.researcher-type-filter {
    display: inline-block;
    padding: .45rem 1.1rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    color: var(--text-secondary);
    font-size: .8125rem;
    font-weight: 600;
    text-decoration: none;
    transition: background-color var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}

.researcher-type-filter:hover {
    color: var(--primary);
    border-color: var(--primary-light);
    background-color: var(--primary-lighter);
    text-decoration: none;
}

.researcher-type-filter.active {
    background-color: var(--primary);
    border-color: var(--primary);
    color: #fff;
}

.researcher-card {
    display: block;
    height: 100%;
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    text-decoration: none;
    transition: box-shadow var(--transition-base), transform var(--transition-base), border-color var(--transition-base);
}

.researcher-card:hover,
.researcher-card:focus {
    box-shadow: var(--shadow-md);
    transform: translateY(-3px);
    border-color: var(--primary-light);
    text-decoration: none;
}

.researcher-card-photo {
    aspect-ratio: 3 / 4;
    overflow: hidden;
    background-color: var(--bg-secondary);
}

.researcher-card-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--transition-base);
}

.researcher-card:hover .researcher-card-photo img {
    transform: scale(1.04);
}

.researcher-card-body {
    padding: 1.1rem 1.25rem 1.35rem;
}

.researcher-card-name {
    font-family: var(--font-display);
    font-size: 1.0625rem;
    font-weight: 600;
    color: var(--text-primary);
    margin: 0 0 .5rem;
    line-height: 1.3;
}

.researcher-card-badge {
    margin-bottom: .5rem;
}

.researcher-card-institution {
    color: var(--text-muted);
    font-size: .8125rem;
    margin: .35rem 0 0;
    line-height: 1.4;
}

.researcher-card-name a {
    color: inherit;
    text-decoration: none;
}

.researcher-card-name a:hover {
    color: var(--primary);
    text-decoration: underline;
}

/* Cards estáticos (advisory board) — sem link para uma página de detalhe
   própria, por isso sem o hover-lift do card inteiro; só a foto/nome/email
   reagem. */
.researcher-card-static {
    cursor: default;
}

.researcher-card-static:hover,
.researcher-card-static:focus {
    box-shadow: none;
    transform: none;
    border-color: var(--border);
}

.researcher-card-static:hover .researcher-card-photo img {
    transform: none;
}

.researcher-card-email {
    display: inline-block;
    margin-top: .6rem;
    color: var(--text-secondary);
    font-size: .8125rem;
    text-decoration: none;
}

.researcher-card-email:hover {
    color: var(--primary);
    text-decoration: underline;
}

.researcher-card-email i {
    color: var(--text-muted);
    margin-right: .25rem;
}

/* Foto de perfil individual (/staff) — mesmo acabamento (cantos
   arredondados, sombra) dos cards, sem ser uma grelha. */
.staff-photo {
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
}

.staff-photo img {
    width: 100%;
    height: auto;
    display: block;
}

/* ==========================================================================
   Publications listing (article/conferences/books/phd/master/other) —
   tabela com metadados extra (revista, DOI, citações) já existentes na BD
   mas nunca mostrados até agora.
   ========================================================================== */


.pub-title {
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.4;
}

.pub-venue {
    font-style: italic;
    color: var(--text-secondary);
    font-size: .875rem;
    margin-top: .15rem;
}

.pub-doi {
    color: var(--text-muted);
    font-size: .75rem;
    margin-top: .25rem;
}

.pub-doi i {
    margin-right: .25rem;
}

.pub-citations {
    display: inline-block;
    margin-left: .4rem;
    padding: .1rem .45rem;
    border-radius: 999px;
    background-color: var(--primary-lighter);
    color: var(--primary-active);
    font-size: .6875rem;
    font-weight: 700;
    white-space: nowrap;
}

.pagination .page-link:hover {
    background-color: var(--primary-lighter);
    color: var(--primary-hover);
}

/* ==========================================================================
   Forms / inputs
   ========================================================================== */

.form-control,
select.form-control,
textarea.form-control {
    border-color: var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.form-control:focus,
select.form-control:focus,
textarea.form-control:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(200, 35, 75, .15);
}

.form-control::placeholder {
    color: var(--text-muted);
}

/* ==========================================================================
   Badges / alerts
   ========================================================================== */

.badge {
    border-radius: var(--radius-sm);
    font-weight: 600;
}

.alert {
    border-radius: var(--radius-md);
    border-width: 1px;
}

.alert-success { background-color: #EAF5EE; border-color: var(--success); color: #1E5636; }
.alert-danger { background-color: #FBEAE6; border-color: var(--error); color: #8A3019; }

/* ==========================================================================
   Footer — 3 bandas de profundidade crescente (newsletter > colunas >
   copyright), tudo na família tonal de --secondary para não introduzir uma
   cor nova, só variar o escurecimento.
   ========================================================================== */

/* O tema vendor dá ao próprio #footer um fundo/borda crimson
   ("#footer { background: #c8234b; border-top: 6px solid #c8234b; }") —
   fora da intenção deste redesenho (só tons de --secondary). As 3 bandas
   abaixo já cobrem tudo com fundo opaco próprio; isto só neutraliza a
   borda/fundo do elemento pai para não haver nenhuma aresta vermelha a
   espreitar. */
#footer {
    background: transparent;
    border-top: 0;
}

.footer-newsletter {
    background-color: var(--secondary);
    padding: 3.5rem 1rem 3rem;
    text-align: center;
}

.footer-newsletter h5 {
    color: #fff;
    font-family: var(--font-display);
}

.footer-newsletter p {
    color: rgba(255, 255, 255, .82);
}

.footer-main {
    background-color: #524C4D;
    padding: 3rem 0 2.5rem;
}

.footer-heading {
    color: #fff;
    font-size: .875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    margin-bottom: 1.1rem;
}

.footer-about p {
    color: rgba(255, 255, 255, .72);
    font-size: .9rem;
    line-height: 1.65;
}

.footer-links {
    list-style: none;
    padding: 0;
    margin: 0;
}

.footer-links li {
    margin-bottom: .6rem;
}

/* #footer (id) do tema vendor tem "#footer a:not(.btn) { color: #777; }" —
   um seletor com ID, mais específico do que uma classe simples. Os
   seletores abaixo repetem o #footer para igualar essa especificidade
   (e ganhar, por carregarem depois no CSS). */
#footer .footer-links a {
    color: rgba(255, 255, 255, .72);
    font-size: .9rem;
    transition: color var(--transition-fast), padding-left var(--transition-fast);
}

#footer .footer-links a:hover {
    color: #fff;
    padding-left: 4px;
}

.footer-contact li {
    display: flex;
    gap: .65rem;
    color: rgba(255, 255, 255, .72);
    font-size: .9rem;
    line-height: 1.5;
    margin-bottom: .85rem;
}

.footer-contact li i {
    color: rgba(255, 255, 255, .45);
    margin-top: .2rem;
    width: 14px;
    flex: 0 0 auto;
}

#footer .footer-contact a {
    color: rgba(255, 255, 255, .72);
}

#footer .footer-contact a:hover {
    color: #fff;
}

.footer-partners,
.partners-strip {
    background-color: #524C4D;
    padding: 0 0 2.5rem;
    border-top: 1px solid rgba(255, 255, 255, .08);
}

.footer-partners-label,
.partners-strip-label {
    text-align: center;
    color: rgba(255, 255, 255, .45);
    font-size: .75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .08em;
    margin: 2rem 0 1.5rem;
}

.footer-partner-logo-wrap,
.partner-logo-wrap {
    height: 60px;
    width: 100%;
    max-width: 150px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.footer-partner-logo,
.partner-logo {
    max-height: 60px;
    max-width: 100%;
    width: auto;
    height: auto;
    opacity: .92;
    transition: opacity var(--transition-fast);
}

.footer-partner-logo-wrap:hover .footer-partner-logo,
.partner-logo-wrap:hover .partner-logo {
    opacity: 1;
}

.footer-funding-note {
    color: rgba(255, 255, 255, .5);
    font-size: .8rem;
    line-height: 1.6;
    text-align: center;
    max-width: 720px;
    margin: 2rem auto 0;
}

.footer-bottom {
    background-color: #3E393A;
    padding: 1.1rem 0;
    text-align: center;
}

.footer-bottom p {
    color: rgba(255, 255, 255, .55);
    font-size: .8125rem;
    margin: 0;
}

@media (max-width: 767px) {
    .footer-main .col-md-4 {
        text-align: center;
    }

    .footer-contact li {
        justify-content: center;
        text-align: left;
    }
}

/* ==========================================================================
   Profile (página de detalhe do investigador)
   ========================================================================== */

.profile-breadcrumb {
    font-size: .875rem;
    color: var(--text-muted);
}

.profile-breadcrumb a {
    color: var(--text-secondary);
}

.profile-breadcrumb a:hover {
    color: var(--primary);
}

.profile-header {
    display: flex;
    gap: 1.75rem;
    align-items: flex-start;
    padding: 2rem;
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.profile-avatar {
    width: 140px;
    height: 140px;
    flex: 0 0 auto;
    border-radius: var(--radius-lg);
    object-fit: cover;
    box-shadow: var(--shadow-sm);
}

.profile-type-badge {
    display: inline-block;
    padding: .25rem .75rem;
    border-radius: 999px;
    background-color: var(--primary-light);
    color: var(--primary-active);
    font-size: .75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.profile-institution {
    color: var(--text-secondary);
    font-size: 1rem;
}

.profile-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.profile-chip {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .35rem .8rem;
    background-color: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-secondary);
    font-size: .8125rem;
    font-weight: 600;
    transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}

a.profile-chip:hover {
    background-color: var(--primary-lighter);
    border-color: var(--primary-light);
    color: var(--primary-active);
}

.profile-chip i {
    font-size: .8em;
    color: var(--primary);
}

.profile-section-title {
    font-size: 1.375rem;
    font-weight: 600;
    margin-bottom: 1rem;
    padding-bottom: .6rem;
    border-bottom: 2px solid var(--border);
}

.profile-bio {
    color: var(--text-primary);
    line-height: 1.75;
    max-width: 75ch;
}

.profile-bio p:last-child {
    margin-bottom: 0;
}

.profile-stats-summary {
    display: flex;
    gap: 2rem;
    margin-bottom: 1.5rem;
}

.profile-stat {
    display: flex;
    flex-direction: column;
}

.profile-stat strong {
    font-family: var(--font-display);
    font-size: 1.75rem;
    color: var(--text-primary);
    line-height: 1.1;
}

.profile-stat span {
    color: var(--text-muted);
    font-size: .8125rem;
    text-transform: uppercase;
    letter-spacing: .03em;
}

.profile-type-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 1.25rem;
    margin-bottom: 2rem;
}

/* Paleta qualitativa dedicada aos 5 tipos de output — deliberadamente
   distinta da paleta semântica do resto do site (não é primary/success/
   etc.), pensada para se ler bem lado a lado como um pequeno "legend" de
   categorias, tal como cores de um gráfico. */
.stat-card {
    --stat-color: var(--primary);
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1.25rem 1.25rem 1.5rem;
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    text-decoration: none;
    position: relative;
    overflow: hidden;
    transition: box-shadow var(--transition-base), transform var(--transition-base), border-color var(--transition-base);
}

.stat-card:hover {
    box-shadow: var(--shadow-md);
    border-color: var(--stat-color);
    transform: translateY(-3px);
    text-decoration: none;
}

.stat-card-icon {
    flex: 0 0 auto;
    width: 52px;
    height: 52px;
    border-radius: var(--radius-md);
    background-color: var(--stat-color);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    transition: transform var(--transition-base);
}

.stat-card:hover .stat-card-icon {
    transform: scale(1.08) rotate(-4deg);
}

.stat-card-body strong {
    display: block;
    font-family: var(--font-display);
    font-size: 1.875rem;
    line-height: 1.1;
    color: var(--text-primary);
}

.stat-card-body span {
    color: var(--text-secondary);
    font-size: .8125rem;
    font-weight: 600;
}

.stat-card-bar {
    position: absolute;
    left: 0;
    bottom: 0;
    height: 4px;
    width: var(--stat-fill, 0%);
    background-color: var(--stat-color);
    border-radius: 0 2px 2px 0;
    transition: width .6s ease;
}

.stat-card:nth-of-type(1) { --stat-color: #C8234B; }
.stat-card:nth-of-type(2) { --stat-color: #C9822E; }
.stat-card:nth-of-type(3) { --stat-color: #1E7A73; }
.stat-card:nth-of-type(4) { --stat-color: #33415C; }
.stat-card:nth-of-type(5) { --stat-color: #807677; }

.profile-chart-card {
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    padding: 1.5rem;
    margin-bottom: 2.5rem;
}

@media (max-width: 767px) {
    .profile-header {
        flex-direction: column;
        align-items: center;
        text-align: center;
        padding: 1.5rem;
    }

    .profile-chips {
        justify-content: center;
    }

    .profile-stats-summary {
        justify-content: center;
    }
}

/* ==========================================================================
   Homepage hero slider — o tema vendor fixa `.slider-container` a 500px de
   altura sem nenhuma media query (confirmado: não há override em lado
   nenhum). Numa imagem ~21:9, isso força um crop muito apertado em ecrãs
   estreitos. Reduz a altura em mobile para um crop menos agressivo.
   ========================================================================== */

/*
   Aqui existia `.slider-container { height: 360px !important }` para mobile.
   Era a causa do problema, não a correção: o Revolution Slider já dimensiona a
   moldura pelo rácio do grid (1170x500, que é 21:9 — o mesmo que o painel pede
   no upload), por isso num ecrã de 390px dava 390x167 e a imagem cabia
   inteira. Os 360px forçados deixavam ~190px de branco por baixo do cartaz.
   Sem esta regra, o telemóvel volta a mostrar a imagem completa. */

/* ==========================================================================
   Barra de contactos do topo em mobile — ocupava 95px do ecrã antes de o
   logótipo sequer aparecer. Passa a 47px, só com os ícones sociais.
   ========================================================================== */

@media (max-width: 575px) {
    /* A morada ocupava 273px dos 360 disponíveis e empurrava os ícones sociais
       para uma grelha 2x2, com a barra a comer 98px antes de o logótipo
       aparecer. No telemóvel ninguém copia uma morada do cabeçalho — e ela
       continua no rodapé, com o resto dos contactos. */
    #header .header-top .header-top-address {
        display: none;
    }

    #header .header-top .social-icons {
        display: flex;
        flex-wrap: nowrap;
        margin: 0;
    }

    #header .header-top .social-icons li {
        margin: 0 0 0 2px;
    }

    #header .header-top .social-icons.social-icons-big li a {
        width: 28px;
        height: 28px;
        line-height: 28px;
        font-size: 0.8rem;
    }

    #header .header-top .header-column.justify-content-end {
        flex: 0 0 auto;
    }

    #header .header-top .header-column.justify-content-start {
        min-width: 0;
    }
}

/* ==========================================================================
   Acessibilidade
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    * {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
}


/* ==========================================================================
   Rede de coautoria (/site/network)

   Estrutura: hero editorial com os números, o grafo como palco com a barra de
   período e o detalhe por dentro da tela, as duplas mais fortes, e um
   diretório único. O SVG é reforço visual; o diretório é a versão acessível e
   a única que serve num telemóvel.
   ========================================================================== */

.visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* Largura máxima do conteúdo. O resto do site usa 90% do ecrã, o que num
   monitor 4K dá ~3400px de linha: a rede ficava uma mancha no meio de uma
   tela enorme, e os números e as duplas espalhavam-se de ponta a ponta.
   1600px alinha com o cabeçalho, que já é estreito e centrado. */
.nw-hero > .container-fluid-90,
.nw-stage-section > .container-fluid-90,
.nw-section > .container-fluid-90 {
    max-width: 1600px;
    margin-left: auto;
    margin-right: auto;
}

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

.nw-hero {
    padding: clamp(2.5rem, 6vw, 4.5rem) 0 2.5rem;
    background:
        radial-gradient(1200px 400px at 85% 0%, var(--primary-lighter), transparent 70%),
        var(--bg);
    border-bottom: 1px solid var(--border);
}

.nw-eyebrow {
    margin: 0 0 .75rem;
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--primary);
}

.nw-title {
    margin: 0 0 1rem;
    max-width: 18ch;
    font-family: var(--font-display);
    font-size: clamp(2.25rem, 5vw, 3.75rem);
    font-weight: 600;
    line-height: 1.05;
    letter-spacing: -.01em;
    color: var(--text-primary);
    text-wrap: balance;
}

.nw-lead {
    margin: 0 0 2rem;
    max-width: 62ch;
    font-size: 1.125rem;
    line-height: 1.65;
    color: var(--text-secondary);
}

.nw-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin: 0 0 1.5rem;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}

.nw-stat { padding: 1.25rem 1.5rem 1.25rem 0; }

.nw-stat + .nw-stat {
    padding-left: 1.5rem;
    border-left: 1px solid var(--border);
}

.nw-stat dt {
    margin: 0 0 .35rem;
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.nw-stat dd {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(1.75rem, 3.5vw, 2.5rem);
    font-weight: 600;
    line-height: 1;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

.nw-stat dd.nw-stat-period { color: var(--primary); }

.nw-rules {
    margin: 0;
    max-width: 70ch;
    font-size: .8125rem;
    line-height: 1.6;
    color: var(--text-muted);
}

/* ── Palco ─────────────────────────────────────────────────────────────── */

.nw-stage-section { padding: 2.5rem 0 1rem; }

.nw-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

/* ── Encontrar no grafo ─────────────────────────────────────────────── */

/* margin-left:auto empurra a pesquisa e a legenda para a direita, juntas,
   em vez de a pesquisa ficar a flutuar no meio da barra. */
.nw-find {
    position: relative;
    display: flex;
    align-items: center;
    flex: 0 1 300px;
    margin-left: auto;
    color: var(--text-muted);
}

.nw-find[hidden] { display: none; }
.nw-find > svg { position: absolute; left: .85rem; pointer-events: none; }

.nw-find input {
    width: 100%;
    min-height: 44px;
    padding: 0 1rem 0 2.5rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    font-size: .9375rem;
    color: var(--text-primary);
}

.nw-find input:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-lighter);
}

.nw-find-list {
    position: absolute;
    z-index: 20;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    max-height: 320px;
    margin: 0;
    padding: 6px;
    overflow-y: auto;
    list-style: none;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: 0 12px 32px -12px rgba(31, 27, 28, .25);
}

.nw-find-list[hidden] { display: none; }

.nw-find-option {
    display: flex;
    align-items: center;
    gap: .6rem;
    min-height: 44px;
    padding: .35rem .6rem;
    border-radius: 10px;
    cursor: pointer;
    color: var(--text-primary);
}

.nw-find-option:hover,
.nw-find-option.is-active { background: var(--bg-secondary); }
.nw-find-option.is-active { box-shadow: inset 3px 0 0 var(--primary); }

.nw-find-face {
    flex: none;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    object-fit: cover;
    font-size: .625rem;
}

.nw-find-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: .875rem;
    font-weight: 600;
}

.nw-find-meta {
    flex: none;
    font-size: .75rem;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

.nw-segmented {
    display: inline-flex;
    flex-wrap: wrap;
    padding: 4px;
    gap: 2px;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 999px;
}

.nw-segment {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    padding: 0 1.1rem;
    border-radius: 999px;
    font-size: .875rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-decoration: none;
    transition: background-color .15s ease, color .15s ease;
}

.nw-segment:hover { color: var(--primary); text-decoration: none; }
.nw-segment:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.nw-segment.is-current {
    background: var(--surface);
    color: var(--primary);
    box-shadow: 0 1px 2px rgba(31, 27, 28, .08), 0 1px 1px rgba(31, 27, 28, .04);
}

.nw-legend {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem 1.75rem;
    margin: .9rem 0 0;
    padding: 0;
    list-style: none;
    font-size: .8125rem;
    color: var(--text-muted);
}

.nw-legend li { display: inline-flex; align-items: center; gap: .6rem; }

.nw-legend-sizes,
.nw-legend-links { display: inline-flex; align-items: center; gap: 4px; }

/* Duas caras, pequena e grande, com o anel branco que as do grafo têm. */
.nw-legend-sizes { align-items: flex-end; gap: 9px; }

.nw-legend-sizes i {
    display: block;
    border-radius: 50%;
    background: #D9D1D2;
    box-shadow: 0 0 0 2px #fff, 0 0 0 3px var(--border);
}

.nw-legend-sizes i:first-child { width: 10px; height: 10px; }
.nw-legend-sizes i:last-child { width: 18px; height: 18px; }

/* Os dois extremos da escala das ligações, com as cores do JS (WEAK e
   STRONG): fina e cinzenta, grossa e vermelha. */
.nw-legend-links i { display: block; width: 16px; border-radius: 2px; }
.nw-legend-links i:first-child { height: 1px; background: rgb(176, 188, 196); }
.nw-legend-links i:last-child { height: 4px; background: rgb(200, 35, 75); opacity: .85; }

.nw-stage {
    position: relative;
    border-radius: 16px;
    overflow: hidden;
    background: radial-gradient(circle at 50% 45%, #fff 0%, var(--bg-secondary) 70%);
    border: 1px solid var(--border);
    box-shadow: 0 1px 2px rgba(31, 27, 28, .04), 0 12px 32px -12px rgba(31, 27, 28, .12);
}

/* Altura presa ao ecrã, não à largura: com proporção fixa, a 4K a tela
   passava dos 1200px e nunca cabia inteira, com o topo sempre por baixo do
   cabeçalho. O desenho adapta-se à caixa (ver o JS), por isso não fica
   esticado nem deformado. */
.network-graph {
    position: relative;
    height: clamp(460px, calc(100vh - 220px), 900px);
}

.network-loading {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    color: var(--text-muted);
    font-size: .875rem;
}

.network-graph.is-ready .network-loading { display: none; }

.network-svg { display: block; width: 100%; height: 100%; }

/* Cor e opacidade vêm do JS, pelo peso de cada ligação (--link-color e
   --link-opacity). Ficam em variáveis, e não em atributos, porque o CSS
   sobrepõe-se aos atributos de apresentação do SVG — e o estado esbatido do
   destaque tem de continuar a ganhar. */
.network-link {
    stroke: var(--link-color, #B0BCC4);
    stroke-opacity: var(--link-opacity, .5);
    transition: stroke-opacity .2s ease;
}

.network-link.is-dimmed { stroke-opacity: .04; }

/* No destaque, as ligações da pessoa ficam todas visíveis, mesmo as fracas. */
.is-highlighting .network-link:not(.is-dimmed) { stroke-opacity: .9; }

.network-node { cursor: pointer; }

/* O círculo é o anel por cima do retrato: separa rostos sobrepostos e
   carrega o estado de destaque sem mexer na imagem. */
.network-node-dot {
    fill: none;
    stroke: #fff;
    stroke-width: 2;
    transition: stroke .15s ease, stroke-width .15s ease;
}

.network-node-photo { transition: opacity .15s ease; }
/* Quem não tem retrato fica com as iniciais em tons neutros. No vermelho
   da marca, um círculo grande era o primeiro sítio para onde se olhava —
   e a página não destaca ninguém. */
.network-node-fallback { fill: #E6DFE0; }

.network-node-initials {
    font-family: var(--font-body);
    font-weight: 700;
    fill: #6B6264;
    pointer-events: none;
}

.network-node:hover .network-node-dot,
.is-highlighting .network-node:not(.is-dimmed) .network-node-dot {
    stroke: var(--primary);
    stroke-width: 3;
}

.network-node.is-dimmed { opacity: .15; }

.network-node-label {
    font-family: var(--font-body);
    font-size: 11px;
    font-weight: 600;
    fill: var(--text-primary);
    paint-order: stroke;
    stroke: #fff;
    stroke-width: 3px;
    stroke-linejoin: round;
    pointer-events: none;
    opacity: 0;
    transition: opacity .15s ease;
}

/* Os nomes que cabem em repouso (o JS escolhe-os pelo espaço livre). Um
   tom abaixo do destaque, para ajudarem a ler a rede sem competir com ele.
   Antes das regras de esbatido e de "ainda não existe", que têm de ganhar. */
.network-node-label.is-landmark { opacity: 1; fill: var(--text-secondary); }

.is-highlighting .network-node-label:not(.is-dimmed) { opacity: 1; fill: var(--text-primary); }
.network-node-label.is-dimmed { opacity: 0; }

/* Detalhe dentro da tela: o grafo fica com a largura toda e a informação
   aparece onde o olhar já está. */
.nw-detail {
    position: absolute;
    left: 1rem;
    bottom: 1rem;
    width: min(300px, calc(100% - 2rem));
    padding: 1rem 1.125rem;
    background: rgba(255, 255, 255, .94);
    backdrop-filter: blur(6px);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 8px 24px -8px rgba(31, 27, 28, .18);
}

/* Só aparece com alguém destacado: em repouso não dizia nada que a dica por
   baixo do grafo não diga. */
.nw-detail[hidden] { display: none; }

/* O JS muda o cartão para o canto oposto ao da pessoa destacada. Em cima
   desce um pouco, para não tapar o botão de ecrã inteiro. */
.nw-detail.is-right { left: auto; right: 1rem; }
.nw-detail.is-top { bottom: auto; top: 4rem; }

/* Com a pessoa só em hover, o cartão não pode roubar o rato ao grafo; fixada,
   precisa dele para o link e o fechar. */
.nw-detail:not(.is-pinned) { pointer-events: none; }

.network-detail-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .5rem;
}

.network-detail-close {
    flex: none;
    width: 32px;
    height: 32px;
    margin: -.4rem -.5rem 0 0;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--text-muted);
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
}

.network-detail-close:hover { background: var(--bg-secondary); color: var(--text-primary); }
.network-detail-close:focus-visible,
.network-detail-open:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.nw-detail:not(.is-pinned) .network-detail-close { display: none; }

.network-detail-open {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-height: 40px;
    margin-top: .75rem;
    padding: 0 1rem;
    border-radius: 999px;
    background: var(--primary);
    color: #fff;
    font-size: .8125rem;
    font-weight: 600;
    text-decoration: none;
}

.network-detail-open:hover { background: #A81C3E; color: #fff; text-decoration: none; }

/* Em hover o botão ainda não serve de nada (não se lhe chega sem sair do nó);
   fica a indicação de que um clique o traz. */
.network-detail-tip { margin: .6rem 0 0; font-size: .75rem; color: var(--text-muted); }
.nw-detail.is-pinned .network-detail-tip { display: none; }

.network-detail-name { margin: 0 0 .15rem; font-size: 1rem; font-weight: 700; color: var(--text-primary); }
.network-detail-meta { margin: 0 0 .75rem; font-size: .75rem; color: var(--text-muted); }
.network-detail-list { list-style: none; margin: 0; padding: 0; }

.network-detail-list li {
    display: flex;
    justify-content: space-between;
    gap: .75rem;
    padding: .3rem 0;
    border-bottom: 1px solid var(--border);
    font-size: .8125rem;
    color: var(--text-secondary);
}

.network-detail-list li:last-child { border-bottom: 0; }
.network-detail-list strong { color: var(--primary); font-variant-numeric: tabular-nums; }

.nw-hint {
    margin: .9rem 0 0;
    max-width: 72ch;
    font-size: .8125rem;
    line-height: 1.6;
    color: var(--text-muted);
}

.nw-empty { color: var(--text-muted); padding: 2rem 0; }

/* ── Ecrã inteiro ──────────────────────────────────────────────────────── */

.nw-fullscreen {
    position: absolute;
    z-index: 5;
    top: .75rem;
    right: .75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: rgba(255, 255, 255, .9);
    color: var(--text-secondary);
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease;
}

.nw-fullscreen[hidden] { display: none; }
.nw-fullscreen:hover { color: var(--primary); border-color: var(--primary); }
.nw-fullscreen:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.nw-fs-exit,
.is-fullscreen .nw-fs-enter { display: none; }
.is-fullscreen .nw-fs-exit { display: block; }

/* Classe posta pelo JS, e não :fullscreen: o Safari antigo só conhece o
   prefixo, e uma lista de seletores com um desconhecido invalida a regra
   inteira. O grafo passa a ocupar a altura que sobra da barra e da linha do
   tempo; o desenho mantém a proporção e centra-se (viewBox). */
.nw-canvas.is-fullscreen {
    display: flex;
    flex-direction: column;
    padding: 1.25rem 1.5rem;
    background: var(--surface);
    overflow: auto;
}

.nw-canvas.is-fullscreen .nw-stage { display: flex; flex: 1; min-height: 0; flex-direction: column; }
.nw-canvas.is-fullscreen .network-graph { flex: 1; height: auto; min-height: 0; }

/* ── Linha do tempo ────────────────────────────────────────────────────── */

/* O que ainda não existe nesse ano some-se, mas continua no seu lugar: as
   posições são as da rede final, e cada pessoa aparece onde vai ficar. */
.network-node,
.network-link { transition: opacity .6s ease, stroke-opacity .2s ease, stroke-width .6s ease, stroke .6s ease; }
.network-node.is-future,
.network-link.is-future,
.network-node-label.is-future { opacity: 0; pointer-events: none; }

/* Quem chega nesse ano: um anel que se expande e desaparece, uma vez. */
.network-node-pulse {
    fill: none;
    stroke: var(--primary);
    stroke-width: 3;
    opacity: 0;
    pointer-events: none;
    transform-box: fill-box;
    transform-origin: center;
}

.network-node.is-new .network-node-pulse { animation: nw-pulse 1.3s ease-out .2s 1 both; }

@keyframes nw-pulse {
    from { opacity: .75; transform: scale(1); }
    to { opacity: 0; transform: scale(1.9); }
}

/* As ligações novas entram acesas e assentam no tom do seu peso. */
.network-link.is-new { animation: nw-link-in 1.3s ease-out .2s 1 both; }

@keyframes nw-link-in {
    from { stroke-opacity: .95; }
    to { stroke-opacity: var(--link-opacity, .5); }
}

.nw-timeline {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    margin-top: 1rem;
    padding: .75rem 1.25rem .75rem .75rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 999px;
}

.nw-timeline[hidden] { display: none; }

.nw-play {
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: .5rem;
    min-height: 44px;
    padding: 0 1.2rem 0 1rem;
    border: 0;
    border-radius: 999px;
    background: var(--primary);
    color: #fff;
    font-size: .875rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .15s ease, transform .15s ease;
}

.nw-play:hover { background: #A81C3E; }
.nw-play:active { transform: scale(.97); }
.nw-play:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }

.nw-pause-icon,
.is-playing .nw-play-icon { display: none; }
.is-playing .nw-pause-icon { display: block; }

.nw-timeline-track { flex: 1; min-width: 0; }

.nw-range {
    display: block;
    width: 100%;
    margin: 0;
    accent-color: var(--primary);
    cursor: pointer;
}

.nw-range:focus-visible { outline: 2px solid var(--primary); outline-offset: 4px; border-radius: 4px; }

/* Cada rótulo fica onde o polegar pára nesse ano. O polegar não chega às
   pontas da faixa — o centro dele anda entre metade da sua largura e o fim
   menos essa metade — daí o desconto de 16px (a largura do polegar). */
.nw-ticks {
    position: relative;
    height: 1rem;
    margin-top: .2rem;
    font-size: .6875rem;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

.nw-ticks span {
    position: absolute;
    top: 0;
    left: calc(var(--p) * (100% - 16px) + 8px);
    transform: translateX(-50%);
}

.nw-now {
    display: flex;
    flex: none;
    flex-direction: column;
    align-items: flex-end;
    gap: .2rem;
    min-width: 9.5rem;
}

.nw-now-count {
    font-size: .75rem;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
    white-space: nowrap;
}

.nw-year {
    font-family: var(--font-display);
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--primary);
}

@media (max-width: 767px) {
    .nw-play-label { display: none; }
    .nw-play { padding: 0; width: 44px; justify-content: center; }
    .nw-timeline { gap: .9rem; padding-right: 1rem; }
    .nw-year { font-size: 1.375rem; }
    .nw-now { min-width: 0; }
    .nw-now-count { display: none; }
}

/* ── Secções ───────────────────────────────────────────────────────────── */

.nw-section { padding: 3.5rem 0 1rem; }
.nw-section-head { margin-bottom: 1.5rem; }

.nw-section-title {
    margin: 0 0 .4rem;
    font-family: var(--font-display);
    font-size: clamp(1.625rem, 3vw, 2.125rem);
    font-weight: 600;
    color: var(--text-primary);
}

.nw-section-note {
    margin: 0;
    max-width: 68ch;
    font-size: .9375rem;
    line-height: 1.6;
    color: var(--text-muted);
}

/* ── Duplas ────────────────────────────────────────────────────────────── */

.nw-pairs {
    display: grid;
    /* 3 colunas fixas, não auto-fill: são sempre 6 duplas, e com 4 colunas
       a segunda fila ficava com dois buracos (e os nomes em cinco linhas). */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.nw-pair {
    position: relative;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1.25rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.nw-pair:hover {
    border-color: var(--primary-light);
    box-shadow: 0 8px 24px -12px rgba(200, 35, 75, .25);
}

.nw-pair-rank {
    position: absolute;
    top: .75rem;
    right: 1rem;
    font-family: var(--font-display);
    font-size: .875rem;
    font-weight: 600;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.nw-pair-faces { display: flex; flex-shrink: 0; }

.nw-pair-face {
    width: 52px;
    height: 52px;
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid var(--surface);
    box-shadow: 0 0 0 1px var(--border);
}

.nw-pair-face + .nw-pair-face { margin-left: -14px; }

.nw-pair-body { min-width: 0; padding-right: 1.5rem; }

.nw-pair-names {
    margin: 0 0 .3rem;
    font-size: .9375rem;
    font-weight: 600;
    line-height: 1.35;
    color: var(--text-primary);
}

.nw-pair-names a { color: inherit; }
/* Um nome por linha: lê-se como um par, e não como um parágrafo. */
.nw-pair-names a:first-child { display: block; }
.nw-pair-names a:hover { color: var(--primary); }
.nw-pair-amp { margin: 0 .2rem; font-family: var(--font-display); color: var(--primary); }

.nw-pair-count { margin: 0; font-size: .8125rem; color: var(--text-muted); }

.nw-pair-count strong {
    font-family: var(--font-display);
    font-size: 1.25rem;
    color: var(--primary);
    font-variant-numeric: tabular-nums;
}

/* ── Diretório ─────────────────────────────────────────────────────────── */

.nw-directory-section { padding-bottom: 4rem; }

.nw-directory-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem 1rem;
    margin-bottom: 1rem;
}

.nw-directory-controls[hidden],
.nw-directory-more[hidden],
.nw-directory-empty[hidden] { display: none; }

.nw-search {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1 1 260px;
    max-width: 360px;
    margin: 0;
    color: var(--text-muted);
}

.nw-search svg { position: absolute; left: .85rem; pointer-events: none; }

.nw-search input {
    width: 100%;
    min-height: 44px;
    padding: 0 1rem 0 2.5rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    font-size: 1rem;
    color: var(--text-primary);
}

.nw-search input:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-lighter);
}

.nw-chips { display: flex; flex-wrap: wrap; gap: .5rem; }

.nw-chip {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    min-height: 44px;
    padding: 0 1rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    font-size: .875rem;
    font-weight: 600;
    color: var(--text-secondary);
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease, background-color .15s ease;
}

.nw-chip span {
    padding: .05rem .45rem;
    border-radius: 999px;
    background: var(--bg-secondary);
    font-size: .75rem;
    font-variant-numeric: tabular-nums;
}

.nw-chip:hover { border-color: var(--primary); color: var(--primary); }
.nw-chip:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.nw-chip.is-current { background: var(--primary); border-color: var(--primary); color: #fff; }
.nw-chip.is-current span { background: rgba(255, 255, 255, .22); }

.nw-table-wrap {
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
}

.nw-table { width: 100%; margin: 0; border-collapse: collapse; font-size: .9375rem; }

.nw-table thead th {
    padding: .85rem 1.25rem;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-muted);
    text-align: left;
}

.nw-table tbody th,
.nw-table tbody td {
    padding: .7rem 1.25rem;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
    font-weight: 400;
    color: var(--text-secondary);
}

.nw-table tbody tr:last-child th,
.nw-table tbody tr:last-child td { border-bottom: 0; }

.nw-table tbody tr:hover { background: var(--primary-lighter); }
.nw-table .nw-num { text-align: right; font-variant-numeric: tabular-nums; }
.nw-muted { color: var(--text-muted) !important; }

.nw-person { display: inline-flex; align-items: center; gap: .75rem; }
.nw-person a { font-weight: 600; color: var(--text-primary); }
.nw-person a:hover { color: var(--primary); }

.nw-person-face {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    border-radius: 50%;
    object-fit: cover;
    box-shadow: 0 0 0 1px var(--border);
}

.nw-avatar-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: #E6DFE0;
    color: #6B6264;
    font-weight: 700;
    font-size: .6875rem;
}

.nw-pair-face.nw-avatar-fallback { font-size: 1rem; }

.nw-directory-empty { margin: 1rem 0 0; color: var(--text-muted); }
.nw-directory-more { margin-top: 1.25rem; text-align: center; }

.nw-more-button {
    min-height: 44px;
    padding: 0 1.5rem;
    border: 1px solid var(--primary);
    border-radius: 999px;
    background: var(--surface);
    font-size: .875rem;
    font-weight: 600;
    color: var(--primary);
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}

.nw-more-button:hover { background: var(--primary); color: #fff; }
.nw-more-button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

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

@media (max-width: 1199px) {
    .nw-pairs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 991px) {
    .nw-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .nw-stat:nth-child(3) { padding-left: 0; border-left: 0; }
    .nw-stat:nth-child(n+3) { border-top: 1px solid var(--border); }
    /* Num ecrã de toque o cartão abre ao tocar numa cara; ocupa a largura
       do palco em baixo, que é onde o polegar chega. */
    .nw-detail,
    .nw-detail.is-right { left: .75rem; right: .75rem; bottom: .75rem; width: auto; }
    .nw-detail.is-top { top: 3.75rem; bottom: auto; }
}

@media (max-width: 575px) {
    /* 57 caras num ecrã de 390px viram uma mancha: aqui o diretório é a
       página, e as duplas contam a mesma história de forma legível. */
    .nw-stage, .nw-hint, .nw-legend, .nw-timeline { display: none; }
    .nw-stat { padding-right: .75rem; }
    .nw-stat + .nw-stat { padding-left: .75rem; }
    /* A primeira de cada fila encosta à margem, como na grelha de 2 acima. */
    .nw-stat:nth-child(odd) { padding-left: 0; }
    .nw-pairs { grid-template-columns: minmax(0, 1fr); }
    .nw-table thead th:nth-child(2),
    .nw-table tbody td:nth-child(2) { display: none; }
    .nw-table tbody th,
    .nw-table tbody td,
    .nw-table thead th { padding-left: .85rem; padding-right: .85rem; }
}

@media (prefers-reduced-motion: reduce) {
    .network-link, .network-node-dot, .network-node-label, .network-node-photo,
    .nw-segment, .nw-chip, .nw-pair, .nw-more-button, .network-node, .nw-play { transition: none; }
    .network-node-pulse { display: none; }
    .network-link.is-new { animation: none; }
}
