/* ==========================================================================
   HOME.CSS — o estilo principal do site
   --------------------------------------------------------------------------
   É a folha de estilo mais importante (a maioria das páginas usa-a). Define
   as cores do tema, o reset, e o estilo da navbar, hero, cartões e footer.
   Estética: fundo escuro, roxo neon, brilho (glow) e animações suaves.
   ========================================================================== */

/* ==========================================================================
   RESET
   O "* { }" aplica-se a TODOS os elementos. Zero as margens e paddings que
   os navegadores põem por defeito (e que variam de navegador para navegador),
   para eu partir de uma base limpa e igual em todo o lado.
   O box-sizing: border-box faz a largura/altura de um elemento incluir a
   borda e o padding — muito mais fácil de calcular tamanhos.
   ========================================================================== */
* { margin: 0; padding: 0; box-sizing: border-box; }

/* ==========================================================================
   VARIÁVEIS DE COR (o tema)
   O ":root" é o topo do documento. As variáveis definidas aqui (--nome)
   ficam disponíveis em TODO o CSS, e uso-as com var(--nome). A vantagem: se
   quiser mudar o roxo do site inteiro, mudo só aqui numa linha.
   Estas são as cores do MODO ESCURO (o padrão).
   ========================================================================== */
:root {
    --fundo: #05010d;      /* fundo geral, quase preto */
    --caixa: #0c0717;      /* fundo dos cartões */
    --texto: #ffffff;      /* texto principal */
    --texto-2: #a0a0a0;    /* texto secundário (mais apagado) */
    --texto-3: rgba(255, 255, 255, 0.35); /* texto muito ténue */
    --roxo: #a445fe;       /* a cor de destaque */
    --roxo-claro: #ba70ff;
    --accent-rgb: 164, 69, 254; /* o roxo em formato R,G,B, para usar com opacidade */
    --borda: rgba(var(--accent-rgb), 0.2);       /* bordas roxas subtis */
    --borda-suave: rgba(var(--accent-rgb), 0.1);
}

/* ==========================================================================
   MODO CLARO
   Quando o JavaScript põe a classe "light-mode" no <body>, estas variáveis
   substituem as de cima. Como todo o CSS usa var(--nome), o site inteiro
   muda de cores de uma só vez, sem eu ter de reescrever nada.
   Truque: no modo claro os tons roxos passam a azul (fica melhor em fundo claro).
   ========================================================================== */
body.light-mode {
    --fundo: #fbf9f6;
    --caixa: #ffffff;
    --texto: #1f160e;
    --texto-2: #5c534c;
    --texto-3: rgba(31, 22, 14, 0.4);
    /* No modo claro os tons roxo/rosa passam todos a azul */
    --roxo: #2f6fed;
    --roxo-claro: #5b93ff;
    --accent-rgb: 47, 111, 237;
    --borda: rgba(var(--accent-rgb), 0.25);
    --borda-suave: rgba(var(--accent-rgb), 0.12);
}

/* scroll-behavior: smooth faz os saltos de âncora (#seccao) serem suaves */
html { scroll-behavior: smooth; }

body {
    background: var(--fundo);
    color: var(--texto);
    font-family: 'Poppins', sans-serif;
    overflow-x: hidden;
    transition: background 0.4s ease, color 0.4s ease;
    position: relative;
}

/* ==========================================================================
   FUNDO DECORATIVO — manchas de luz suaves atrás de todo o site.
   Fixo (acompanha o scroll), com z-index negativo para nunca interferir
   com cliques. O Hero da Home tem fundo próprio opaco por cima disto,
   por isso ali não aparece — como pedido.
   ========================================================================== */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(circle at 12% 15%, rgba(var(--accent-rgb), 0.12) 0%, transparent 42%),
        radial-gradient(circle at 88% 10%, rgba(var(--accent-rgb), 0.09) 0%, transparent 38%),
        radial-gradient(circle at 80% 85%, rgba(var(--accent-rgb), 0.10) 0%, transparent 42%),
        radial-gradient(circle at 15% 90%, rgba(var(--accent-rgb), 0.08) 0%, transparent 38%),
        radial-gradient(circle at 50% 50%, rgba(var(--accent-rgb), 0.04) 0%, transparent 60%);
    pointer-events: none;
}

::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: var(--fundo); }
::-webkit-scrollbar-thumb { background: rgba(var(--accent-rgb), 0.4); border-radius: 10px; }

:focus { outline: none; }
:focus-visible { outline: 2px solid var(--roxo); outline-offset: 3px; border-radius: 4px; }

img { user-select: none; }

/* ==========================================================================
   NAVBAR — a barra do topo
   Técnicas usadas aqui, que vale a pena reconhecer:
   - position: fixed → a barra "cola" ao topo do ecrã e não se mexe com o
     scroll (top/left/right a 0 esticam-na de ponta a ponta).
   - z-index: 100 → o "andar" em que a barra fica; um valor alto garante que
     ela fica POR CIMA do resto do conteúdo quando este passa por baixo.
   - display: flex + justify-content: space-between → põe o logo, o menu e o
     botão de CV em linha, com o espaço livre distribuído entre eles.
   - backdrop-filter: blur → desfoca o que está por trás da barra (efeito de
     vidro fosco / glassmorphism).
   ========================================================================== */
.navbar {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 4rem;
    background: rgba(5, 1, 13, 0.7);
    -webkit-backdrop-filter: blur(14px); /* versão para Safari */
    backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--borda-suave);
}

body.light-mode .navbar { background: rgba(251, 249, 246, 0.8); }

.navbar-logo { display: flex; align-items: center; }

.navbar-logo img {
    height: 3rem;
    max-height: 3rem; /* cinto de segurança: o logo nunca estica a navbar */
    width: auto;
    display: block;
    /* O PNG já traz o glow próprio; eu só reforço um pouco */
    filter: drop-shadow(0 0 10px rgba(var(--accent-rgb), 0.5));
    transition: filter 0.3s ease, transform 0.3s ease;
}

.navbar-logo:hover img {
    filter: drop-shadow(0 0 18px rgba(var(--accent-rgb), 0.85));
    transform: scale(1.06);
}

.navbar-menu {
    display: flex;
    gap: 2.6rem;
}

.navbar-menu a {
    color: var(--texto-2);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 500;
    position: relative;
    padding: 0.4rem 0;
    transition: color 0.3s ease, text-shadow 0.3s ease;
}

.navbar-menu a:hover { color: var(--texto); }

/* Página ativa: roxo neon + glow + ponto por baixo */
.navbar-menu a.ativo {
    color: var(--roxo-claro);
    text-shadow: 0 0 14px rgba(var(--accent-rgb), 0.7);
}

/* O pontinho roxo por baixo do link ativo do menu.
   ::after é um "pseudo-elemento": cria um elemento extra por CSS, sem estar
   no HTML. content:'' é obrigatório para ele aparecer. Uso position:absolute
   + left:50% + translateX(-50%) para o centrar exatamente por baixo do link.
   O box-shadow com a mesma cor cria o efeito de brilho (glow). */
.navbar-menu a.ativo::after {
    content: '';
    position: absolute;
    bottom: -4px;
    left: 50%;
    transform: translateX(-50%);
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--roxo);
    box-shadow: 0 0 8px var(--roxo);
}

/* Botão CV — borda roxa, glow no hover, ligeiro scale */
.btn-cv {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.55rem 1.4rem;
    border: 1px solid var(--roxo);
    border-radius: 0.6rem;
    color: var(--texto);
    text-decoration: none;
    font-size: 0.88rem;
    font-weight: 600;
    background: rgba(var(--accent-rgb), 0.08);
    transition: all 0.3s ease;
}

.btn-cv-icon {
    width: 1rem;
    height: 1rem;
    filter: invert(45%) sepia(90%) saturate(2500%) hue-rotate(250deg) brightness(105%);
    transition: transform 0.3s ease;
}

.btn-cv:hover {
    background: rgba(var(--accent-rgb), 0.18);
    box-shadow: 0 0 20px rgba(var(--accent-rgb), 0.5), inset 0 0 12px rgba(var(--accent-rgb), 0.15);
    transform: scale(1.05);
}

.btn-cv:hover .btn-cv-icon { transform: translateY(2px); }

/* ==========================================================================
   HERO
   ========================================================================== */
.hero {
    position: relative;
    z-index: 1;
    background: var(--fundo);  /* opaco: tapa o fundo decorativo do body só aqui */
    min-height: 100vh;
    display: grid;
    grid-template-columns: 1.1fr 1fr;
    align-items: center;
    gap: 3rem;
    padding: 7.5rem 4rem 4rem;
    overflow: hidden;
}

/* Partículas/estrelas do fundo — os pontos são criados pelo JS */
.hero-particulas {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(ellipse 55% 45% at 78% 45%, rgba(var(--accent-rgb), 0.14) 0%, transparent 65%),
        radial-gradient(ellipse 40% 40% at 10% 85%, rgba(var(--accent-rgb), 0.08) 0%, transparent 60%);
}

.particula {
    position: absolute;
    border-radius: 50%;
    background: var(--roxo-claro);
    opacity: 0.5;
    animation: brilharParticula var(--dur, 4s) ease-in-out infinite alternate;
}

@keyframes brilharParticula {
    from { opacity: 0.15; transform: scale(0.8); }
    to   { opacity: 0.7;  transform: scale(1.2); box-shadow: 0 0 6px var(--roxo-claro); }
}

.hero-esquerda {
    position: relative;
    z-index: 2;
    /* Eu empurro o bloco do texto para a direita, como na demo */
    padding-left: 3.5rem;
    animation: entrarFade 0.9s ease both;
}

@keyframes entrarFade {
    from { opacity: 0; transform: translateY(24px); }
    to   { opacity: 1; transform: translateY(0); }
}

.hero-saudacao {
    color: var(--roxo-claro);
    font-size: 1.05rem;
    font-weight: 500;
    margin-bottom: 0.2rem;
}

.hero-eusou {
    color: var(--texto-2);
    font-size: 1.05rem;
    margin-bottom: 0.4rem;
}

/* O nome com typing effect */
.hero-nome {
    font-size: clamp(2.8rem, 5vw, 4.2rem);
    font-weight: 800;
    line-height: 1.06;
    min-height: 2.3em; /* eu reservo as 2 linhas para o layout não saltar durante o typing */
    margin-bottom: 0.6rem;
}

/* A segunda linha (apelido) fica roxa — o JS envolve-a num span */
.hero-nome .apelido {
    color: var(--roxo);
    text-shadow: 0 0 30px rgba(var(--accent-rgb), 0.55);
}

/* Cursor a piscar do typing */
.cursor-typing {
    display: inline-block;
    width: 3px;
    height: 0.9em;
    margin-left: 6px;
    background: var(--roxo-claro);
    vertical-align: -0.08em;
    box-shadow: 0 0 8px var(--roxo-claro);
    animation: piscarCursor 0.85s steps(1) infinite;
}

@keyframes piscarCursor { 50% { opacity: 0; } }

.hero-cargo {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--texto);
    margin-bottom: 1rem;
}

.hero-descricao {
    color: var(--texto-2);
    font-size: 0.95rem;
    line-height: 1.7;
    max-width: 440px;
    margin-bottom: 1.8rem;
}

/* ====== CARTÃO ROTATIVO (2+ anos → 12+ projetos → 100% foco) ====== */
.cartao-rotativo {
    /* Sem retângulo: só o ícone e os textos, limpos sobre o fundo.
       display:flex (nível de bloco) garante que o botão fica POR BAIXO. */
    display: flex;
    width: fit-content;
    align-items: center;
    gap: 0.9rem;
    padding: 0.4rem 0;
    margin-bottom: 2rem;
    min-width: 250px;
    transition: opacity 0.45s ease, transform 0.45s ease;
}

/* Estado escondido durante a troca (o JS liga/desliga) */
.cartao-rotativo.a-trocar {
    opacity: 0;
    transform: translateY(6px);
}

.cartao-rotativo-icone {
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 50%;
    background: rgba(var(--accent-rgb), 0.15);
    border: 1px solid var(--borda);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    box-shadow: 0 0 14px rgba(var(--accent-rgb), 0.3);
}

.cartao-rotativo-icone img {
    width: 1.2rem;
    height: 1.2rem;
    filter: invert(45%) sepia(90%) saturate(2500%) hue-rotate(250deg) brightness(105%);
}

.cartao-rotativo-textos { display: flex; flex-direction: column; }

.cartao-numero {
    font-size: 1.45rem;
    font-weight: 800;
    color: var(--texto);
    line-height: 1.1;
}

.cartao-label {
    font-size: 0.8rem;
    color: var(--texto-2);
}

/* ====== BOTÃO VER PROJETOS — com shine effect ====== */
.btn-ver-projetos {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.85rem 1.9rem;
    /* Um tom ligeiramente mais escuro que --roxo: o texto branco em cima
       do roxo original só tinha contraste 4.32:1 (falha o mínimo de
       4.5:1 do WCAG AA) — visualmente é quase impercetível a diferença */
    background: #9425fe;
    color: #fff;
    text-decoration: none;
    font-size: 0.95rem;
    font-weight: 600;
    border-radius: 0.7rem;
    overflow: hidden;
    box-shadow: 0 0 22px rgba(var(--accent-rgb), 0.45);
    transition: all 0.3s ease;
}

.btn-ver-projetos:hover {
    transform: scale(1.04);
    box-shadow:
        0 0 30px rgba(var(--accent-rgb), 0.75),
        0 0 60px rgba(255, 255, 255, 0.12);
}

/* A seta é o SVG fornecido — fica BRANCA (exceção pedida) */
.btn-seta {
    width: 1.15rem;
    height: 1.15rem;
    filter: brightness(0) invert(1);
    transition: transform 0.3s ease;
}

.btn-ver-projetos:hover .btn-seta { transform: translateX(4px); }

/* O reflexo luminoso que atravessa o botão no hover */
.btn-shine {
    position: absolute;
    top: 0;
    left: -80%;
    width: 45%;
    height: 100%;
    background: linear-gradient(100deg, transparent 0%, rgba(255,255,255,0.35) 50%, transparent 100%);
    transform: skewX(-20deg);
    transition: none;
}

.btn-ver-projetos:hover .btn-shine {
    animation: atravessarShine 0.7s ease forwards;
}

@keyframes atravessarShine {
    to { left: 130%; }
}

/* ====== ILUSTRAÇÃO PIRATA — fundida no fundo do hero ====== */
.hero-direita {
    position: relative;
    z-index: 2;
    display: flex;
    justify-content: flex-end;
    animation: entrarFade 0.9s ease 0.15s both;
}

.ilustracao-wrap {
    position: relative;
    width: min(660px, 100%);
    /* Flutuação muito subtil — a imagem é grande, o movimento é discreto */
    animation: flutuar 7s ease-in-out infinite;
}

@keyframes flutuar {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-8px); }
}

.ilustracao-pirata {
    display: block;
    width: 100%;
    height: auto;
    /* A imagem agora tem fundo transparente REAL — integra-se
       nativamente em qualquer fundo, sem truques de blend.
       Eu só suavizo os tons e dou uma sombra a assentá-la. */
    filter:
        saturate(0.85) contrast(0.97)
        drop-shadow(0 22px 40px rgba(0, 0, 0, 0.5));
}

/* Uma leve "tinta" roxa por cima para a ilustração (tons castanho/azul)
   conversar com a paleta neon do site, sem a descaracterizar */
.ilustracao-tinta {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(ellipse 70% 60% at 50% 45%, rgba(var(--accent-rgb), 0.10) 0%, transparent 70%);
    mix-blend-mode: screen;
}

/* ==========================================================================
   MARQUEE DE TECNOLOGIAS — infinito, sem quebras, com circle-dots
   ========================================================================== */
.marquee-tech {
    border-top: 1px solid var(--roxo);
    border-bottom: 1px solid var(--roxo);
    box-shadow:
        0 -1px 18px rgba(var(--accent-rgb), 0.25),
        0 1px 18px rgba(var(--accent-rgb), 0.25);
    padding: 1.1rem 0;
    overflow: hidden;
    background: rgba(var(--accent-rgb), 0.03);
}

/* A faixa do marquee (a fila de tecnologias que desliza sozinha).
   width: max-content faz a faixa ser tão larga quanto o conteúdo (não se
   limita à largura do ecrã), para os itens ficarem todos numa linha. */
.marquee-faixa {
    display: flex;
    align-items: center;
    /* SEM gap aqui: todo o espaçamento vive DENTRO de cada item,
       para as duas metades duplicadas medirem exatamente 50% cada
       e o loop reiniciar sem pausa nem salto */
    width: max-content;
    /* A animação abaixo desloca a faixa continuamente para a esquerda.
       "infinite" repete para sempre; "linear" mantém velocidade constante;
       a duração vem de uma variável (--marquee-dur) definida pelo JS. */
    animation: deslizarMarquee var(--marquee-dur, 28s) linear infinite;
    /* will-change avisa o navegador que isto vai animar, para ele otimizar. */
    will-change: transform;
}

/* A animação em si: mover de 0% até -50% da própria largura.
   Como o JS duplicou o conteúdo (bloco+bloco), quando chega a -50% a segunda
   cópia está exatamente onde a primeira começou → o salto de volta ao início
   é invisível e parece um deslize infinito. */
@keyframes deslizarMarquee {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

.marquee-item {
    display: flex;
    align-items: center;
    gap: 2.4rem;
    padding-right: 2.4rem; /* o espaçamento até ao próximo item */
    color: var(--texto);
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.5px;
    white-space: nowrap;
}

.marquee-dot {
    width: 0.55rem;
    height: 0.55rem;
    flex-shrink: 0;
    filter: invert(45%) sepia(90%) saturate(2500%) hue-rotate(250deg) brightness(110%)
            drop-shadow(0 0 4px var(--roxo));
}

/* ==========================================================================
   PROJETOS EM DESTAQUE — auto-scroll lento para a direita, pausa no hover
   ========================================================================== */
.projetos-destaque {
    padding: 4.5rem 4rem 3rem;
}

.seccao-cabecalho {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 2rem;
}

.seccao-cabecalho h2 {
    font-size: 1.7rem;
    font-weight: 700;
}

.link-ver-todos {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--roxo-claro);
    text-decoration: none;
    font-size: 0.88rem;
    font-weight: 500;
    transition: all 0.3s ease;
}

.link-ver-todos img {
    width: 1rem;
    filter: invert(45%) sepia(90%) saturate(2500%) hue-rotate(250deg) brightness(105%);
    transition: transform 0.3s ease;
}

.link-ver-todos:hover { text-shadow: 0 0 12px rgba(var(--accent-rgb), 0.6); }
.link-ver-todos:hover img { transform: translateX(4px); }

.projetos-mask { overflow: hidden; }

.projetos-track {
    display: flex;
    gap: 1.4rem;
    width: max-content;
    /* Desloca lentamente PARA A DIREITA (como pedido) */
    animation: deslizarProjetos var(--projetos-dur, 45s) linear infinite;
    will-change: transform;
}

@keyframes deslizarProjetos {
    from { transform: translateX(-50%); }
    to   { transform: translateX(0); }
}

/* Pausa quando o rato está sobre a faixa */
.projetos-track:hover { animation-play-state: paused; }

/* ====== CARD DE PROJETO ====== */
.projeto-card {
    flex: 0 0 360px;
    background: var(--caixa);
    border: 1px solid var(--borda-suave);
    border-radius: 0.9rem;
    overflow: hidden;
    transition: transform 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}

.projeto-card:hover {
    transform: scale(1.035) translateY(-4px);
    border-color: var(--roxo);
    box-shadow: 0 0 30px rgba(var(--accent-rgb), 0.4);
}

.projeto-card-imagem {
    height: 190px;
    background: var(--fundo);
    background-image:
        linear-gradient(rgba(var(--accent-rgb), 0.07) 1px, transparent 1px),
        linear-gradient(90deg, rgba(var(--accent-rgb), 0.07) 1px, transparent 1px);
    background-size: 14px 14px;
    overflow: hidden;
}

.projeto-card-imagem img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top;
    transition: transform 0.4s ease;
}

.projeto-card:hover .projeto-card-imagem img { transform: scale(1.05); }

.projeto-card-corpo { padding: 1.2rem 1.3rem 1.4rem; }

.projeto-card-corpo h3 {
    font-size: 1.08rem;
    font-weight: 700;
    margin-bottom: 0.4rem;
}

.projeto-card-corpo p {
    color: var(--texto-2);
    font-size: 0.8rem;
    line-height: 1.55;
    margin-bottom: 0.9rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Badges de tecnologia com a cor oficial de cada marca
   (a cor vem por style="--tech-cor: ..." definida no JS) */
.projeto-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin-bottom: 1.1rem;
}

.tech-badge {
    font-size: 0.68rem;
    font-weight: 600;
    padding: 0.26rem 0.7rem;
    border-radius: 0.35rem;
    color: var(--texto);
    border: 1px solid var(--tech-cor, var(--roxo));
    background: color-mix(in srgb, var(--tech-cor, var(--roxo)) 12%, transparent);
}

.projeto-card-botoes {
    display: flex;
    gap: 0.6rem;
}

.btn-projeto {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    padding: 0.55rem 0.9rem;
    border-radius: 0.5rem;
    font-size: 0.78rem;
    font-weight: 600;
    text-decoration: none;
    transition: all 0.25s ease;
}

.btn-projeto img { width: 0.95rem; }

.btn-projeto-demo {
    background: var(--roxo);
    color: #fff;
    box-shadow: 0 0 12px rgba(var(--accent-rgb), 0.35);
}

.btn-projeto-demo:hover {
    background: var(--roxo-claro);
    box-shadow: 0 0 20px rgba(var(--accent-rgb), 0.6);
}

.btn-projeto-github {
    border: 1px solid var(--borda);
    color: var(--texto);
    background: transparent;
}

.btn-projeto-github img {
    filter: invert(45%) sepia(90%) saturate(2500%) hue-rotate(250deg) brightness(105%);
}

.btn-projeto-github:hover {
    border-color: var(--roxo);
    box-shadow: 0 0 14px rgba(var(--accent-rgb), 0.35);
}

/* Mensagem se a BD estiver sem projetos */
.projetos-vazio {
    color: var(--texto-2);
    padding: 2rem;
    font-size: 0.9rem;
}

/* ==========================================================================
   CONTACTOS — "Vamos conversar?"
   ========================================================================== */
.contactos {
    padding: 4.5rem 4rem 5rem;
    text-align: center;
    position: relative;
}

.contactos::before {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse 50% 60% at 50% 100%, rgba(var(--accent-rgb), 0.09) 0%, transparent 70%);
    pointer-events: none;
}

.contactos-titulo {
    font-size: 2rem;
    font-weight: 800;
    margin-bottom: 0.6rem;
}

.contactos-descricao {
    color: var(--texto-2);
    font-size: 0.95rem;
    line-height: 1.6;
    margin-bottom: 2.6rem;
}

.contactos-grid {
    position: relative;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.2rem;
    max-width: 1050px;
    margin: 0 auto;
}

.contacto-card {
    background: var(--caixa);
    border: 1px solid var(--borda-suave);
    border-radius: 0.9rem;
    padding: 1.8rem 1.2rem;
    text-decoration: none;
    color: var(--texto);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.55rem;
    transition: all 0.3s ease;
}

.contacto-card:hover {
    transform: scale(1.04) translateY(-4px);
    border-color: var(--roxo);
    box-shadow: 0 0 26px rgba(var(--accent-rgb), 0.4);
}

.contacto-card-estatico { cursor: default; }

.contacto-icone {
    width: 3.2rem;
    height: 3.2rem;
    border-radius: 50%;
    background: transparent;
    border: 1px solid var(--roxo);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 0.3rem;
    box-shadow: 0 0 16px rgba(var(--accent-rgb), 0.25);
    transition: box-shadow 0.3s ease;
}

.contacto-card:hover .contacto-icone {
    box-shadow: 0 0 24px rgba(var(--accent-rgb), 0.55);
}

.contacto-icone img {
    width: 1.35rem;
    height: 1.35rem;
    filter: invert(45%) sepia(90%) saturate(2500%) hue-rotate(250deg) brightness(105%);
}

.contacto-card h3 { font-size: 0.95rem; font-weight: 700; }

.contacto-card span {
    font-size: 0.76rem;
    color: var(--roxo-claro);
    word-break: break-all;
}

/* ==========================================================================
   FOOTER minimalista
   ========================================================================== */
.footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1.4rem 4rem;
    border-top: 1px solid var(--borda-suave);
}

.footer-esquerda {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    color: var(--texto-2);
    font-size: 0.85rem;
}

/* O nome e a nota da IA ficam empilhados (um por cima do outro), em vez de
   lado a lado. O <span> do nome e o da nota são irmãos dentro do
   .footer-esquerda, por isso agrupo-os numa coluna com este wrapper. */
.footer-texto {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.footer-logo-img {
    height: 2.1rem;
    filter: drop-shadow(0 0 8px rgba(var(--accent-rgb), 0.4));
}

/* Nota de transparência sobre as ilustrações geradas por IA.
   Em itálico e discreta — mas uso --texto-2 (não --texto-3), porque este
   último não tinha contraste suficiente para passar o WCAG AA. */
.footer-nota-ia {
    font-style: italic;
    font-size: 0.75rem;
    color: var(--texto-2);
}

/* No modo claro a transparência funciona igual; só ajusto a sombra
   para tons quentes e desligo a tinta roxa (desnecessária sobre claro) */
body.light-mode .ilustracao-pirata {
    filter:
        saturate(0.9)
        drop-shadow(0 18px 36px rgba(31, 22, 14, 0.3));
}

body.light-mode .ilustracao-tinta { display: none; }

/* ==========================================================================
   SIDEBAR DE DEFINIÇÕES — faixa lateral minimalista
   Fechada: uma faixa roxa fina de cantos redondos, colada à esquerda.
   Aberta: um meio-pill (cantos direitos circulares) com os botões
   a abrirem para baixo em cascata.
   ========================================================================== */
.sidebar-definicoes {
    position: fixed;
    left: 0;
    top: 40%;
    z-index: 150;
    display: flex;
    /* O menu vem antes do botão no DOM; eu inverto a ordem VISUAL
       para o handle ficar em cima e o menu descer por baixo dele */
    flex-direction: column-reverse;
    align-items: flex-start;
}

/* ====== O HANDLE (a faixa) — estado fechado ====== */
.handle-definicoes {
    width: 14px;
    height: 110px;
    border: none;
    border-radius: 0 12px 12px 0;
    cursor: pointer;
    background: linear-gradient(180deg, var(--roxo-claro) 0%, var(--roxo) 100%);
    box-shadow:
        0 0 14px rgba(var(--accent-rgb), 0.55),
        inset 2px 0 6px rgba(0, 0, 0, 0.25);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1),
                height 0.35s cubic-bezier(0.4, 0, 0.2, 1),
                border-radius 0.35s ease,
                box-shadow 0.35s ease;
    /* Um brilho que respira, para convidar ao clique */
    animation: respirarHandle 3.2s ease-in-out infinite;
}

@keyframes respirarHandle {
    0%, 100% { box-shadow: 0 0 12px rgba(var(--accent-rgb), 0.45); }
    50%      { box-shadow: 0 0 22px rgba(var(--accent-rgb), 0.8); }
}

.handle-definicoes:hover {
    width: 20px;
    animation: none;
    box-shadow: 0 0 26px rgba(var(--accent-rgb), 0.9);
}

/* O ícone da engrenagem só aparece quando o painel abre */
.handle-icone {
    width: 1.1rem;
    height: 1.1rem;
    filter: brightness(0) invert(1);
    opacity: 0;
    transform: rotate(-90deg) scale(0.6);
    transition: opacity 0.3s ease 0.1s, transform 0.4s ease 0.1s;
}

/* ====== ESTADO ABERTO ======
   O menu está ANTES do botão no DOM, por isso quando ganha .active
   eu alcanço o handle com o seletor de irmão seguinte (~).
   (Evito o :has() de propósito — já nos falhou no Edge.) */
.definicoes-menu.active ~ .handle-definicoes {
    width: 58px;
    height: 48px;
    border-radius: 0 24px 0 0;   /* vira o topo do meio-pill */
    animation: none;
}

.definicoes-menu.active ~ .handle-definicoes .handle-icone {
    opacity: 1;
    transform: rotate(0) scale(1);
}

/* ====== O PAINEL (menu) — abre para baixo ====== */
.definicoes-menu {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.55rem;
    width: 58px;
    max-height: 0;
    padding: 0;
    overflow: hidden;
    background: linear-gradient(180deg,
        rgba(var(--accent-rgb), 0.22) 0%,
        rgba(12, 7, 23, 0.96) 26%);
    border-radius: 0 0 24px 0;   /* o fundo do meio-pill */
    box-shadow: 0 0 18px rgba(var(--accent-rgb), 0.35);
    transition: max-height 0.45s cubic-bezier(0.4, 0, 0.2, 1),
                padding 0.35s ease;
}

.definicoes-menu.active {
    max-height: 420px;
    padding: 0.7rem 0 0.9rem;
}

/* Os botões descem em cascata quando o painel abre */
.def-opcao-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    cursor: pointer;
    background: var(--caixa);
    border: 1px solid var(--borda);
    text-decoration: none;
    flex-shrink: 0;
    opacity: 0;
    transform: translateY(-10px);
    transition: opacity 0.3s ease, transform 0.3s ease,
                border-color 0.25s ease, box-shadow 0.25s ease;
}

.definicoes-menu.active .def-opcao-btn {
    opacity: 1;
    transform: translateY(0);
}

/* O efeito cascata: cada botão entra um pouco depois do anterior */
.definicoes-menu.active > .def-opcao-btn:nth-child(1),
.definicoes-menu.active > .linguas-wrapper:nth-child(2) .def-opcao-btn { transition-delay: 0.08s; }
.definicoes-menu.active > .def-opcao-btn:nth-child(1) { transition-delay: 0.05s; }
.definicoes-menu.active > .linguas-wrapper .def-opcao-btn { transition-delay: 0.13s; }
.definicoes-menu.active > a.def-opcao-btn { transition-delay: 0.21s; }

.def-opcao-btn:hover {
    border-color: var(--roxo);
    box-shadow: 0 0 14px rgba(var(--accent-rgb), 0.5);
}

.def-opcao-btn img {
    width: 1.05rem;
    filter: brightness(0) invert(1);
    opacity: 0.9;
}

body.light-mode .def-opcao-btn img { filter: brightness(0); }

/* ====== LÍNGUAS — as bandeiras abrem PARA BAIXO, dentro do painel ====== */
.linguas-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.55rem;
    opacity: 1; /* o wrapper em si não anima — os filhos sim */
}

.submenu-linguas {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}

.submenu-linguas.active {
    max-height: 200px;
}

.btn-lingua {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.2rem;
    height: 2.2rem;
    border-radius: 50%;
    cursor: pointer;
    background: var(--caixa);
    border: 1px solid var(--borda);
    transition: all 0.25s ease;
}

.btn-lingua img { width: 1.25rem; }

.btn-lingua:hover,
.btn-lingua.active-lang {
    border-color: var(--roxo);
    box-shadow: 0 0 10px rgba(var(--accent-rgb), 0.4);
}

/* ==========================================================================
   JORNADA — linha do tempo horizontal entre os projetos e os contactos
   ========================================================================== */
.jornada {
    padding: 2.5rem 4rem;
}

@media (max-width: 899px) { .jornada { padding: 2rem 1.4rem; } }

.jornada-linha {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.5rem;
    position: relative;
}

/* A linha horizontal que atravessa os pontos */
.jornada-linha::before {
    content: '';
    position: absolute;
    top: 1.1rem;
    left: 5%;
    right: 5%;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--borda) 15%, var(--borda) 85%, transparent);
    z-index: 0;
}

.jornada-item {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
}

.jornada-ponto {
    width: 2.2rem;
    height: 2.2rem;
    border-radius: 50%;
    background: var(--caixa);
    border: 1px solid var(--roxo);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 0.9rem;
    box-shadow: 0 0 14px rgba(var(--accent-rgb), 0.4);
}

.jornada-ponto img {
    width: 1rem;
    height: 1rem;
    filter: invert(45%) sepia(90%) saturate(2500%) hue-rotate(250deg) brightness(105%);
}

.jornada-ano {
    color: var(--roxo-claro);
    font-size: 0.82rem;
    font-weight: 700;
    margin-bottom: 0.3rem;
}

.jornada-item h3 {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--texto);
    margin-bottom: 0.4rem;
}

.jornada-item p {
    font-size: 0.8rem;
    line-height: 1.55;
    color: var(--texto-2);
}

@media (max-width: 899px) {
    .jornada-linha {
        grid-template-columns: 1fr;
        gap: 2rem;
    }
    .jornada-linha::before {
        top: 0;
        bottom: 0;
        left: 1.1rem;
        right: auto;
        width: 1px;
        height: auto;
        background: linear-gradient(180deg, transparent, var(--borda) 10%, var(--borda) 90%, transparent);
    }
    .jornada-item { padding-left: 3rem; }
    .jornada-ponto { position: absolute; left: 0; top: 0; }
}

/* ==========================================================================
   EFEITO CORDEL — canvas que segue o cursor (a lógica vive no home.js)
   ========================================================================== */
.canvas-cordel {
    position: fixed;
    inset: 0;
    z-index: 90;
    pointer-events: none;
}

@media (max-width: 899px), (prefers-reduced-motion: reduce) {
    .canvas-cordel { display: none; }
}

/* ==========================================================================
   SKELETONS — placeholders animados enquanto a API carrega
   ========================================================================== */
.projeto-card-skeleton {
    position: relative;
    overflow: hidden;
    background: var(--caixa);
}

.projeto-card-skeleton::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
        90deg,
        transparent 0%,
        rgba(var(--accent-rgb), 0.12) 50%,
        transparent 100%
    );
    animation: shimmerSkeleton 1.6s ease-in-out infinite;
}

@keyframes shimmerSkeleton {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(100%); }
}

/* ==========================================================================
   Item 5: menu de definições no modo claro
   O painel usava uma cor de fundo fixa (roxo escuro) e os ícones sempre
   a branco — no modo claro isso ficava escuro/ilegível em vez de seguir
   o tema. Agora ambos se adaptam.
   ========================================================================== */
body.light-mode .definicoes-menu {
    background: linear-gradient(180deg,
        rgba(var(--accent-rgb), 0.12) 0%,
        rgba(255, 255, 255, 0.98) 26%);
    box-shadow: 0 0 18px rgba(var(--accent-rgb), 0.2);
}

body.light-mode .def-opcao-btn img,
body.light-mode .handle-icone {
    filter: brightness(0);
}

/* ==========================================================================
   MODO CLARO — ícones monocromáticos passam de roxo para azul
   Estes ícones são preto-e-branco na origem e ganham cor através de uma
   cadeia de filtros CSS (hue-rotate) fixa — por defeito dá roxo. No
   modo claro, sobreponho um hue-rotate diferente (190deg) que dá azul,
   para toda a paleta ficar consistente.
   ========================================================================== */
body.light-mode .btn-cv-icon,
body.light-mode .cartao-rotativo-icone img,
body.light-mode .marquee-dot,
body.light-mode .link-ver-todos img,
body.light-mode .btn-projeto-github img,
body.light-mode .contacto-icone img,
body.light-mode .jornada-ponto img,

body.light-mode .input-com-icone img,
body.light-mode .resposta-rapida-item img,
body.light-mode .orbital-card-icone img,
body.light-mode .orbital-centro img,
body.light-mode .banner-final-icone img,
body.light-mode .login-input-wrapper img {
    filter: invert(45%) sepia(90%) saturate(2500%) hue-rotate(190deg) brightness(105%);
}

/* ==========================================================================
   BOTÃO HAMBÚRGUER (navbar)
   No DESKTOP fica escondido — o menu cabe todo em linha.
   No MOBILE aparece (ver mobile.css) e passa a ser a forma de abrir o menu.
   As 3 barras são <span> vazios; quando o menu abre, transformam-se num X
   com rotações (ver a classe .aberto no mobile.css).
   ========================================================================== */
.btn-hamburguer {
    display: none;              /* escondido no desktop */
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 44px;
    height: 44px;
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
}

.btn-hamburguer span {
    display: block;
    width: 22px;
    height: 2px;
    background: var(--texto);
    border-radius: 2px;
    /* A transição é o que faz as barras virarem um X suavemente */
    transition: transform 0.3s ease, opacity 0.3s ease;
}
