/* Homepage - Elevate Solutions */
/* Assinatura visual: "A Ascensão" - o duplo chevron da marca (elevar) continua
   como divisor diagonal entre secções (.section-chevron-divider) e no ícone
   do logótipo; removido do fundo do hero a pedido do utilizador (achava o
   motivo de fundo/marca de água "atrás" dos cartões de vidro visualmente
   pesado - ver nota junto a .hero-visual abaixo). */

/* Fundo "estrelado" subtil (Épico 21) - textura imersiva pedida pelo
   utilizador (inspirada num mockup com fundo de nebulosa), construída só com
   radial-gradient (sem imagem, sem JS, zero pedido de rede): cada camada é
   um ponto de 1-1.5px, `background-size: 480px 480px` faz o conjunto repetir
   em mosaico por todo o hero. Estático - não anima, por isso não interfere
   com prefers-reduced-motion. Opacidades baixas (0.3-0.55) para ler como
   textura de fundo, nunca competir com o texto/cartões de vidro por cima. */
.hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(1.5px 1.5px at 8% 22%, rgba(255, 255, 255, 0.55), transparent),
    radial-gradient(1px 1px at 22% 68%, rgba(255, 255, 255, 0.4), transparent),
    radial-gradient(1.5px 1.5px at 38% 12%, rgba(93, 195, 240, 0.5), transparent),
    radial-gradient(1px 1px at 55% 45%, rgba(255, 255, 255, 0.35), transparent),
    radial-gradient(1.5px 1.5px at 68% 78%, rgba(255, 255, 255, 0.5), transparent),
    radial-gradient(1px 1px at 82% 30%, rgba(93, 195, 240, 0.45), transparent),
    radial-gradient(1.5px 1.5px at 92% 60%, rgba(255, 255, 255, 0.4), transparent),
    radial-gradient(1px 1px at 15% 90%, rgba(255, 255, 255, 0.3), transparent),
    var(--navy-900);
  background-size: 480px 480px;
  padding-block: var(--space-9) var(--space-10);
  isolation: isolate;
}

/* Vídeo de fundo do hero (Épico 23) - loop curto (5s) fornecido pelo
   utilizador, `object-fit: cover` para preencher `.hero` seja qual for o
   rácio do ecrã. z-index -1: fica atrás do fundo estrelado acima (que
   continua definido como `background` do próprio `.hero`, por isso serve
   de alternativa visível caso o vídeo falhe a carregar) e atrás do
   spotlight de cursor (`.hero::before`, z-index 0, Épico 20) - o brilho que
   segue o rato continua visível por cima do vídeo. `pointer-events: none`
   porque é puramente decorativo. */
.hero-bg-video {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

/* Scrim escuro por cima do vídeo (mesmo princípio já usado em
   .case-card-cover::after para fotos de portfólio) - garante que o texto
   sobre o hero mantém o mesmo contraste validado em docs/brand.md
   independentemente do brilho de cada frame do vídeo. Mais escuro no fundo
   (onde a faixa de confiança e o resto da página continuam) do que no topo. */
.hero-bg-scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgba(22, 33, 58, 0.55), rgba(22, 33, 58, 0.8));
  pointer-events: none;
}

/* WCAG 2.2.2 (Pause, Stop, Hide): um vídeo em loop automático com mais de 5s
   precisa de mecanismo de pausa - em vez de construir um botão só para
   isto, a via mais simples e consistente com o resto do site é não o
   reproduzir de todo sob movimento reduzido (mesmo princípio já aplicado a
   toda a animação do site). O fundo estrelado/navy de `.hero` (acima)
   continua visível normalmente - nunca fica sem fundo nenhum. */
@media (prefers-reduced-motion: reduce) {
  .hero-bg-video { display: none; }
}

/* @keyframes ascend vive em components.css - partilhada com a entrada
   mais discreta dos .page-header nas restantes páginas (Épico 14). */

/* Layout 2 colunas em desktop (Épico 15.8) - em ecrã estreito continua em
   coluna única, com o painel visual empilhado depois do texto na ordem
   natural do DOM (o valor da proposta lê-se primeiro). */
.hero-grid {
  position: relative;
}
@media (min-width: 900px) {
  .hero-grid {
    display: grid;
    grid-template-columns: 1.15fr 1fr;
    gap: var(--space-8);
    align-items: center;
  }
}

.hero-content {
  position: relative;
  max-width: 720px;
}

/* Spotlight de cursor no hero (Épico 20) - brilho radial que segue o rato
   por cima do fundo do hero. É, deliberadamente, a única fonte de
   profundidade atrás dos cartões de vidro depois de o utilizador ter
   pedido a remoção do glow estático (.hero-visual-glow) e da marca de água
   do chevron (.hero-visual-mark, .hero-chevrons) - fundo limpo em repouso,
   só reage ao gesto de quem visita. z-index 0: `.hero::before` é o primeiro
   "filho" de `.hero` na árvore, mas pinta depois de qualquer elemento com
   z-index negativo (não há nenhum, desde que o Épico 20 removeu
   .hero-chevrons) e antes de .hero-grid (posicionado, ordem de árvore
   seguinte) - fica visualmente atrás do texto/cartões, nunca sobre eles.
   Coordenadas atualizadas via --hero-spot-x/--hero-spot-y em
   assets/js/main.js, mesmo guard de desktop/
   rato real e reduced-motion do spotlight de cards em components.css. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .hero { --hero-spot-x: 50%; --hero-spot-y: 30%; }
  .hero::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background: radial-gradient(500px circle at var(--hero-spot-x) var(--hero-spot-y), rgba(93, 195, 240, 0.10), transparent 70%);
    opacity: 0;
    transition: opacity var(--duration-slow) var(--ease-out);
    pointer-events: none;
  }
  .hero:hover::before { opacity: 1; }
}

/* Painel visual do hero (Épico 17 - reformulado a pedido do utilizador: a
   caixa sólida com gradiente + chips do Épico 16 foi considerada "feia").
   Nova composição: cartões de vidro (glassmorphism) flutuantes, ligeiramente
   rodados, cada um a resumir uma área real de trabalho (Website, Automação
   & IA, Sistema interno) com um mini-preview abstrato de linhas - nunca um
   dashboard com números fabricados, só forma e ícones reais já usados no
   resto da página. Sem caixa/fundo sólido: os cartões flutuam diretamente
   sobre o navy do hero. Épico 20: removida a marca de água do chevron atrás
   dos cartões (.hero-visual-mark), o motivo de fundo do hero
   (.hero-chevrons) e o painel de glow retangular atrás dos cartões
   (.hero-visual-glow, sentido como um "quadrado de gradiente" indesejado) -
   fundo limpo, só o novo spotlight de cursor (acima) a dar profundidade,
   sem nenhuma forma/glow fixa por trás. */
.hero-visual {
  position: relative;
  min-height: 300px;
  margin-top: var(--space-8);
}
@media (min-width: 900px) {
  .hero-visual { margin-top: 0; min-height: 420px; }
}

/* Cartões flutuantes - mini-preview abstrato (ícone + "linhas" + rótulo) de
   3 áreas reais de trabalho, nunca métricas fabricadas. */
.hero-visual-card {
  position: absolute;
  z-index: 1;
  width: 172px;
  padding: var(--space-4);
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 44px -16px rgba(6, 12, 26, 0.55);
  opacity: 0;
  /* Arrastável (Épico 24) - cursor de "pega" convida à interação mesmo antes
     de o utilizador tentar; touch-action:none impede o scroll da página de
     competir com o arrasto em ecrãs táteis; user-select:none evita
     selecionar o texto do rótulo enquanto se arrasta. Ver assets/js/main.js
     para a lógica (Pointer Events - rato e touch com o mesmo código). */
  cursor: grab;
  touch-action: none;
  user-select: none;
  transition: transform var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out);
}
.hero-visual-card.is-dragging {
  z-index: 20 !important;
  cursor: grabbing;
  transition: none;
}
.hero-visual-card:hover {
  opacity: 1;
  transform: translateY(-6px) rotate(0deg);
  box-shadow: 0 30px 54px -14px rgba(6, 12, 26, 0.65);
  z-index: 5;
}
/* Correção (Épico 24) - "animation: none" aqui tinha um efeito colateral
   grave: ao sair do hover, o browser reaplica a declaração `animation`
   original (card-in-a/b/c, com o mesmo animation-delay de 620/720/820ms),
   o que REINICIA a animação de entrada do zero em vez de simplesmente a
   deixar em paz - o cartão "desaparecia" (voltava a opacity:0, rodado, 28px
   abaixo) sempre que o rato saía, até a animação replay terminar. Como a
   entrada só corre uma vez (sem "infinite") e fica no estado final graças a
   "forwards", não há necessidade nenhuma de cancelar a animação no hover -
   ao fim de ~1.4s de vida da página já terminou e o hover normal por cima
   (opacity/transform/box-shadow, que ganham por especificidade de :hover)
   é todo o controlo que é preciso. */
.hvc-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  background: rgba(93, 195, 240, 0.22);
  color: var(--sky-500);
  margin-bottom: var(--space-3);
}
.hvc-icon svg { width: 18px; height: 18px; }
.hvc-lines { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--space-3); }
.hvc-lines span { display: block; height: 6px; border-radius: 3px; background: rgba(255, 255, 255, 0.24); }
.hvc-lines span:nth-child(1) { width: 100%; }
.hvc-lines span:nth-child(2) { width: 74%; }
.hvc-lines span:nth-child(3) { width: 52%; }
.hvc-label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-100);
  color: var(--text-on-dark);
  margin: 0;
}

.hero-visual-card--a { top: 0; left: 2%; animation: card-in-a var(--duration-slow) var(--ease-out) forwards; animation-delay: 620ms; }
.hero-visual-card--b { top: 32%; right: 0; z-index: 2; animation: card-in-b var(--duration-slow) var(--ease-out) forwards; animation-delay: 720ms; }
.hero-visual-card--c { bottom: 2%; left: 24%; z-index: 3; animation: card-in-c var(--duration-slow) var(--ease-out) forwards; animation-delay: 820ms; }

/* Rotação mantida constante do início ao fim de cada animação (só
   opacidade/translateY mudam) - evita o cartão "girar" ao entrar, que
   pareceria descontrolado; o ângulo já é o que dá o efeito de composição
   flutuante, não precisa de animar também. */
@keyframes card-in-a { from { opacity: 0; transform: translateY(28px) rotate(-7deg); } to { opacity: 1; transform: translateY(0) rotate(-7deg); } }
@keyframes card-in-b { from { opacity: 0; transform: translateY(28px) rotate(6deg); } to { opacity: 1; transform: translateY(0) rotate(6deg); } }
@keyframes card-in-c { from { opacity: 0; transform: translateY(28px) rotate(-4deg); } to { opacity: 1; transform: translateY(0) rotate(-4deg); } }

/* Em ecrãs estreitos, 3 cartões sobrepostos e rodados ficam apertados
   demais - reduz para os 2 mais representativos, mesmo critério de "menos
   elementos decorativos em mobile" já usado no resto do site. */
@media (max-width: 559px) {
  .hero-visual { min-height: 260px; }
  .hero-visual-card--c { display: none; }
  .hero-visual-card--a { top: 0; left: 4%; }
  .hero-visual-card--b { top: 40%; right: 4%; }
}

.hero h1 {
  color: var(--white);
  margin-bottom: var(--space-4);
}
/* Abaixo de 900px o h1 herdava só o clamp genérico de base.css (pensado
   para títulos curtos de uma linha) - com as duas frases forçadas por <br>
   ("Inovação que faz" / "o seu negócio crescer", ver index.html), esse
   clamp era demasiado grande em ecrãs estreitos (320-375px): a 1ª frase
   ainda quebrava sozinha a meio, dando 4 linhas em vez de 2-3 e um hero
   desnecessariamente alto. Clamp próprio, mais contido, calibrado para a
   1ª frase caber sempre numa única linha a partir dos 320px. */
@media (max-width: 899px) {
  .hero h1 { font-size: clamp(1.55rem, 1rem + 3.6vw, 2.75rem); }
}
@media (min-width: 900px) {
  /* Épico 17: reduzido de --fs-900 (72px, exclusivo do hero) para --fs-800
     (56px, o mesmo tamanho dos outros H1 do site) - pedido explícito do
     utilizador para um título mais compacto; substitui a decisão do
     Épico 14 de reservar um salto de escala só para a homepage.
     Reduzido depois para --fs-700 (44px, o mesmo tamanho usado em mobile)
     para o título mais longo "Inovação que faz / o seu negócio crescer."
     caber com folga nas duas linhas forçadas por <br> em index.html, sem
     risco de um dos três grupos de palavras ainda assim transbordar. */
  .hero h1 { font-size: var(--fs-700); }
}
.hero .lead { color: var(--text-on-dark-muted); margin-bottom: var(--space-7); max-width: 56ch; }

/* Sequência de entrada do hero: eyebrow → H1 → lead → CTA sobem em sequência,
   sincronizados com a animação dos chevrons acima (80/220/360ms) - o mesmo
   gesto de "ascensão" a acontecer em uníssono no fundo e no primeiro plano,
   em vez de duas animações desligadas uma da outra. O H1 já não participa
   deste grupo (Épico 22) - tem a sua própria entrada palavra a palavra, ver
   .hero-kinetic abaixo, mas começa no mesmo instante (220ms). */
.hero-content .eyebrow,
.hero-content .lead,
.hero-content .btn-group {
  opacity: 0;
  transform: translateY(24px);
  animation: ascend var(--duration-slow) var(--ease-out) forwards;
}
.hero-content .eyebrow { animation-delay: 100ms; }
.hero-content .lead { animation-delay: 360ms; }
.hero-content .btn-group { animation-delay: 500ms; }
/* Os cartões do painel visual (Épico 17) entram por último, a fechar a
   sequência - cada um com o seu próprio keyframe (card-in-a/b/c, acima),
   com atraso a partir dos 620ms, depois do CTA (500ms). */

/* Título cinético do hero (Épico 22) - cada palavra entra na sua própria
   "máscara" (.kw-mask, overflow:hidden) com um pequeno atraso em cascata a
   partir dos 220ms (o mesmo instante em que o H1 entrava como bloco único
   antes desta história) - 30ms entre palavras, hoje 10 palavras (~270ms de
   cascata), sobrepondo-se de propósito com a entrada do lead (360ms): é o
   mesmo tipo de sobreposição natural já usado no resto da coreografia do
   hero, não um erro de sincronização. Palavra inteira por span, nunca letra
   a letra - o texto real do H1 fica intacto para leitores de ecrã (nenhum
   conteúdo novo introduzido, só divisão visual). */
.hero-kinetic { overflow: visible; }
.hero-kinetic .kw-mask {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
}
.hero-kinetic .kw {
  display: inline-block;
  opacity: 0;
  transform: translateY(110%);
  animation: kinetic-word var(--duration-slow) var(--ease-out) forwards;
}
@keyframes kinetic-word {
  to { opacity: 1; transform: translateY(0); }
}
.hero-kinetic .kw-mask:nth-child(1) .kw { animation-delay: 220ms; }
.hero-kinetic .kw-mask:nth-child(2) .kw { animation-delay: 250ms; }
.hero-kinetic .kw-mask:nth-child(3) .kw { animation-delay: 280ms; }
.hero-kinetic .kw-mask:nth-child(4) .kw { animation-delay: 310ms; }
.hero-kinetic .kw-mask:nth-child(5) .kw { animation-delay: 340ms; }
.hero-kinetic .kw-mask:nth-child(6) .kw { animation-delay: 370ms; }
.hero-kinetic .kw-mask:nth-child(7) .kw { animation-delay: 400ms; }
.hero-kinetic .kw-mask:nth-child(8) .kw { animation-delay: 430ms; }
.hero-kinetic .kw-mask:nth-child(9) .kw { animation-delay: 460ms; }
.hero-kinetic .kw-mask:nth-child(10) .kw { animation-delay: 490ms; }

@media (prefers-reduced-motion: reduce) {
  .hero-content .eyebrow,
  .hero-content .lead,
  .hero-content .btn-group { opacity: 1; transform: none; animation: none; }
  .hero-kinetic .kw { opacity: 1; transform: none; animation: none; }
  .hero-visual-card { opacity: 1; animation: none; }
  .hero-visual-card--a { transform: rotate(-7deg); }
  .hero-visual-card--b { transform: rotate(6deg); }
  .hero-visual-card--c { transform: rotate(-4deg); }
}

/* Parallax subtil ao scroll (Épico 15.4) removido no Épico 20 junto com o
   próprio .hero-chevrons que animava - não havia mais nada de fundo no hero
   para aplicar parallax depois da remoção do motivo de chevron. O parallax
   do CTA final (.section-cta::before, components.css) mantém-se intocado. */

/* Lista de princípios ("Metodologia") - família de layout deliberadamente
   diferente da grelha de cards já usada em "O que fazemos" (Épico 15.6:
   a mesma família de layout não deve repetir-se na mesma página - skill
   /ui-ux-expert, Fase 2). Sem cartão (sem fundo/borda/sombra própria), só
   ícone + título + texto, separados por divisores finos em vez de espaço
   entre cartões - o mesmo conteúdo, uma composição genuinamente distinta. */
.principle-row {
  display: grid;
  gap: var(--space-6);
}
@media (min-width: 700px) {
  .principle-row { grid-template-columns: repeat(3, 1fr); gap: 0; }
  .principle { padding-inline: var(--space-6); border-left: 1px solid var(--neutral-200); }
  .principle:first-child { padding-left: 0; border-left: none; }
  .principle-row > [data-reveal]:nth-child(2) { transition-delay: 90ms; }
  .principle-row > [data-reveal]:nth-child(3) { transition-delay: 180ms; }
}
.principle-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-lg);
  height: var(--icon-lg);
  color: var(--sky-700);
  margin-bottom: var(--space-3);
}
.principle-icon svg { width: 100%; height: 100%; }
.principle h3 { font-size: var(--fs-400); margin-bottom: var(--space-2); }
.principle p { color: var(--text-muted); font-size: var(--fs-300); }

.hero-divider {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 48px;
}
.hero-divider path { fill: var(--white); }

/* Faixa de credibilidade (Épico 15.9) - 4 afirmações curtas de valor com
   ícone, logo a seguir ao hero. Deliberadamente FORA do próprio `.hero`
   (não mais um elemento de texto dentro dele): a Fase 2 da skill
   /ui-ux-expert limita o hero a eyebrow+título+subtexto+CTA - uma faixa de
   confiança extra pertence a uma secção dedicada logo abaixo, que é
   exatamente o que `.trust-bar` já era antes desta história (uma frase
   única). Texto reaproveitado do que já lá estava ("Metodologia clara,
   comunicação direta e entrega no prazo combinado") + um 4º ponto que já
   existia como valor aprovado em /sobre/ ("Sem gestores de conta
   intermédios") - nenhuma afirmação nova por inventar. */
.trust-bar {
  padding-block: var(--space-6);
  border-bottom: 1px solid var(--neutral-200);
}
.trust-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3) var(--space-7);
  list-style: none;
  padding: 0;
  margin: 0;
}
.trust-list li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--text-muted);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-200);
  white-space: nowrap;
}
.trust-list svg {
  width: var(--icon-sm);
  height: var(--icon-sm);
  color: var(--sky-700);
  flex-shrink: 0;
}

/* Faixa de estatísticas reais (Épico 21) - 4 números verificáveis, dados
   diretamente pelo utilizador (nunca inventados - ver
   docs/epics/epic-21-transformacao-estatisticas.md). Mesma composição "sem
   cartão" já usada em .principle-row (Épico 15.6): divisores finos em vez de
   fundo/borda/sombra por item, para não repetir pela terceira vez a família
   de layout "grelha de cards" já usada em "O que fazemos"/"Tecnologias". */
.stats-strip {
  display: grid;
  gap: var(--space-6);
  text-align: center;
}
@media (min-width: 700px) {
  .stats-strip { grid-template-columns: repeat(4, 1fr); gap: 0; }
  .stat-item { padding-inline: var(--space-5); border-left: 1px solid rgba(255, 255, 255, 0.12); }
  .stat-item:first-child { border-left: none; }
  .stats-strip > [data-reveal]:nth-child(2) { transition-delay: 90ms; }
  .stats-strip > [data-reveal]:nth-child(3) { transition-delay: 180ms; }
  .stats-strip > [data-reveal]:nth-child(4) { transition-delay: 270ms; }
}
.stat-value {
  display: block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--fs-700);
  color: var(--sky-500);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--space-2);
}
.stat-caption {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-200);
  color: var(--text-on-dark-muted);
}

/* Grelha "Do Manual ao Inteligente" (Épico 21) - pares antes/depois, família
   de layout nova (linha horizontal com seta), não repete nenhuma das
   famílias já existentes na página (grelha de cards com ícone, lista sem
   cartão de .principle-row, faixa sem cartão de .stats-strip acima). Fundo
   navy-700 sobre o navy-800 de `.section-alt` - mesmo par de contraste já
   validado noutros componentes (`.card` dentro de `.section-alt`). */
.transform-grid {
  display: grid;
  gap: var(--space-5);
}
.transform-pair {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  background: var(--navy-700);
  border-radius: var(--radius-md);
}
.transform-before,
.transform-after {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-300);
  line-height: var(--lh-tight);
}
.transform-before { color: var(--text-on-dark-muted); }
.transform-after { color: var(--white); }
.transform-tag {
  display: block;
  font-size: var(--fs-100);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--space-1);
}
.transform-before .transform-tag { color: var(--text-on-dark-muted); }
.transform-after .transform-tag { color: var(--sky-500); }
.transform-arrow {
  width: var(--icon-md);
  height: var(--icon-md);
  color: var(--sky-500);
  flex-shrink: 0;
}
@media (max-width: 559px) {
  .transform-pair { grid-template-columns: 1fr; text-align: center; }
  .transform-arrow { transform: rotate(90deg); margin-inline: auto; }
}
@media (min-width: 700px) {
  .transform-grid > [data-reveal]:nth-child(2) { transition-delay: 90ms; }
  .transform-grid > [data-reveal]:nth-child(3) { transition-delay: 180ms; }
  .transform-grid > [data-reveal]:nth-child(4) { transition-delay: 270ms; }
}

/* Porquê a Elevate - sequência de passos com badge circular + setas
   conectoras (Épico 16: substitui a "escada" de padding-bottom do Épico 15.3
   por uma composição mais dinâmica e "produto", pedido explícito do
   utilizador para aproximar o site do impacto visual de uma referência
   fornecida). A ordem continua a ser real: são etapas do processo, não uma
   numeração decorativa. */
.steps {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  counter-reset: step;
}
@media (min-width: 700px) {
  .steps { flex-direction: row; align-items: flex-start; gap: 0; }
  /* Linha de conexão entre os badges (pedido do utilizador: dar à secção um
     ar mais "produto"/interativo). z-index:-1 (não 0/omitido) é o que a
     mantém sempre atrás dos .step normais - descendentes de z-index negativo
     pintam antes de conteúdo em fluxo normal, mesmo sendo ela própria
     posicionada; sem isto a linha ficaria por cima dos badges, não atrás
     (ver nota igual em .step::before, mesmo raciocínio). Só aparece nos
     espaços entre círculos - o próprio badge, opaco, tapa-a onde passa por
     baixo dele, dando o efeito de "contas ligadas por um fio". */
  .steps::before {
    content: "";
    position: absolute;
    top: 32px;
    left: 0;
    right: 0;
    height: 2px;
    background: linear-gradient(90deg, transparent, rgba(93, 195, 240, 0.35) 12%, rgba(93, 195, 240, 0.35) 88%, transparent);
    z-index: -1;
  }
}
.step {
  position: relative;
  counter-increment: step;
  text-align: center;
}
@media (min-width: 700px) {
  .step { flex: 1; min-width: 0; }
}
.step-badge {
  position: relative;
  width: 64px;
  height: 64px;
  margin: 0 auto var(--space-4);
  border-radius: 50%;
  background: linear-gradient(155deg, var(--sky-100), #DCEFFB);
  color: var(--sky-700);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 10px 22px -10px rgba(93, 195, 240, 0.6);
  transition: transform var(--duration-base) var(--ease-out);
}
.step-badge svg { width: 26px; height: 26px; }
.step:hover .step-badge { transform: translateY(-3px) scale(1.06); }
/* Anel que aparece no hover à volta do badge - transição de estado disparada
   diretamente pelo cursor (não um loop automático), por isso sem guard de
   prefers-reduced-motion, mesmo critério já usado no resto do site para
   hovers simples (ex: .hero-visual-card:hover). */
.step-badge::after {
  content: "";
  position: absolute;
  inset: -7px;
  border-radius: 50%;
  border: 1.5px solid var(--sky-500);
  opacity: 0;
  transform: scale(0.82);
  transition: opacity var(--duration-base) var(--ease-out), transform var(--duration-base) var(--ease-out);
}
.step:hover .step-badge::after { opacity: 1; transform: scale(1); }
.step h3 { font-size: var(--fs-400); margin-bottom: var(--space-2); }
.step h3::before { content: counter(step, decimal-leading-zero) ". "; color: var(--sky-700); }
.step p { color: var(--text-muted); font-size: var(--fs-200); }

/* Fluxo de chevrons entre passos (substitui a seta única) - três marcas "›"
   sobrepostas, a mesma construção do chevron já usado no logótipo e nos
   divisores de secção (section-chevron-divider), só rodada 90° e repetida -
   "seta abstrata" pedida pelo utilizador em vez de um ícone de seta
   literal. Só a partir do breakpoint em que a sequência fica lado a lado,
   mesmo critério da linha de conexão acima. */
.step-flow { display: none; }
@media (min-width: 700px) {
  .step-flow {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 40px;
    /* Alinha com o centro vertical do step-badge (64px), mesmo cálculo já
       usado na antiga .step-arrow. */
    margin-top: 22px;
    color: var(--sky-500);
  }
  .step-flow-chevron {
    width: 15px;
    height: 15px;
    margin-left: -7px;
  }
  .step-flow-chevron:first-child { margin-left: 0; }
}
/* "Marcha" em cascata das três chevrons - loop automático e decorativo,
   por isso atrás do guard (ao contrário do anel de hover acima, que é
   disparado pelo utilizador). Em reduced-motion ficam simplesmente
   estáticas e igualmente opacas, sem perder a leitura de "seta". */
@media (min-width: 700px) and (prefers-reduced-motion: no-preference) {
  .step-flow-chevron {
    opacity: 0.3;
    animation: chevron-flow 1.6s var(--ease-out) infinite;
  }
  .step-flow-chevron:nth-child(1) { animation-delay: 0ms; }
  .step-flow-chevron:nth-child(2) { animation-delay: 160ms; }
  .step-flow-chevron:nth-child(3) { animation-delay: 320ms; }
}
@keyframes chevron-flow {
  0%, 100% { opacity: 0.3; transform: translateX(0); }
  40% { opacity: 1; transform: translateX(3px); }
}

/* Faixa de tecnologias (Épico 15.10, reforçada no Épico 16 com um painel
   com cartão) - logótipos reais (HTML, CSS, JavaScript, React/React Native),
   cores oficiais de marca via dados de Simple Icons, SVG inline (sem pedido
   de rede extra, mesma disciplina do resto do site). O 5º item ("Integrações
   de IA") usa o mesmo ícone já usado no card "Automações e IA" acima nesta
   página - de propósito não é um logótipo de terceiros: não há nenhum
   fornecedor de IA confirmado, e inventar um logotipo para parecer uma marca
   real seria desonesto. */
.tech-panel {
  background: var(--white);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius-lg);
  padding: var(--space-7) var(--space-6);
  box-shadow: var(--shadow-sm);
}
.tech-strip {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--space-7) var(--space-8);
  list-style: none;
  padding: 0;
  margin: 0;
}
.tech-strip li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  transition: transform var(--duration-base) var(--ease-out);
}
.tech-strip li:hover { transform: translateY(-3px); }
/* Pedido do utilizador: em ecrãs ≤425px, 2 colunas fixas em vez do wrap
   natural do flex (que ainda cabia 3 por linha em telemóveis maiores,
   deixando o último item sozinho numa 2ª linha desequilibrada). Grid força
   sempre 2 por linha (5 itens = 2/2/1, o último centrado por
   justify-items). */
@media (max-width: 425px) {
  .tech-strip {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    justify-items: center;
  }
}
.tech-strip svg { width: 32px; height: 32px; }
.tech-strip span {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-100);
  color: var(--text-muted);
}

/* Revelação sequencial dos passos (Épico 15.3, seletores atualizados no
   Épico 16 porque os .step-arrow passaram a ser irmãos intercalados no DOM
   - as posições nth-child dos 4 `.step` deixaram de ser 1/2/3/4 e passaram a
   1/3/5/7): reaproveita o sistema [data-reveal]/is-visible já existente
   (components.css/main.js) - só acrescenta o atraso em escada entre eles,
   mesma convenção de 90ms já usada nas grelhas [data-reveal] (components.css).
   Cada passo "entra em destaque" um a seguir ao outro conforme o scroll
   avança. Só a partir do breakpoint em que os passos ficam lado a lado; em
   coluna única já revelam um a um naturalmente ao scroll, sem precisar de
   atraso artificial (mesmo critério do Épico 14.0). */
@media (min-width: 700px) {
  .steps > .step:nth-child(3) { transition-delay: 90ms; }
  .steps > .step:nth-child(5) { transition-delay: 180ms; }
  .steps > .step:nth-child(7) { transition-delay: 270ms; }
}

/* ============================================================
   HOMEPAGE - ELEMENTOS EXCLUSIVOS DO TEMA ESCURO (Épico 18, âmbito
   reduzido no Épico 19). O tema escuro em si (fundo, cabeçalho,
   .card, .section-alt, .case-card, .section-cta, rodapé, etc.) foi
   entretanto extraído para assets/css/theme-dark.css e passou a
   carregar em TODAS as páginas (Épico 19 - pedido do utilizador para
   replicar "a mesma lógica, em termos de cores e efeitos" no resto do
   site). O que fica aqui é só o que não existe fora da homepage:
   o painel do hero, o glow atrás de "O que fazemos", os badges
   circulares do processo, a faixa de tecnologias e a faixa de
   confiança - elementos com markup que só a homepage tem. */

/* Hero: o swoosh branco entre o hero e a trust-bar já não marca uma
   transição real (as duas secções ficam agora com o mesmo fundo
   navy-900) - escondido em vez de deixado com uma cor errada. */
.hero-divider { display: none; }

/* Faixa de credibilidade (Épico 15.9) - herda o fundo escuro do body,
   só o texto/ícone/borda precisam de tom on-dark. */
.trust-bar { border-bottom-color: rgba(255, 255, 255, 0.1); }
.trust-list li { color: var(--text-on-dark-muted); }
.trust-list svg { color: var(--sky-500); }

/* Glow ambiente atrás do título de "O que fazemos" - mesma técnica
   do glow do hero/CTA (radial-gradient decorativo, sem imagem),
   reforça o momento de abertura da secção sem competir com o texto
   (z-index negativo, atrás de tudo). */
#servicos { position: relative; overflow: hidden; }
#servicos::before {
  content: "";
  position: absolute;
  top: -10%;
  left: 50%;
  width: 900px;
  max-width: 140%;
  height: 500px;
  transform: translateX(-50%);
  background: radial-gradient(circle, rgba(93, 195, 240, 0.16), transparent 65%);
  pointer-events: none;
  z-index: 0;
}
#servicos .container { position: relative; z-index: 1; }
/* Os 6 cartões de serviço já não têm "Saber mais" (Épico 25 - página
   /servicos/ removida) - sem link nenhum lá dentro, o cursor genérico de
   .card:hover (components.css) continuava a fingir que era clicável.
   Mantém toda a restante interatividade do :hover (borda, sombra, ícone
   a levantar) - só anula o cursor. */
#servicos .card:hover { cursor: default; }

/* Painel de tecnologias - só a homepage tem .tech-panel/.tech-strip. */
.tech-panel {
  background: var(--navy-700);
  border-color: transparent;
  box-shadow: 0 18px 34px -22px rgba(0, 0, 0, 0.7);
}
.tech-strip span { color: var(--text-on-dark-muted); }

/* Badges circulares do processo - só a homepage tem esta versão rica de
   .steps (o .step h3::before/.step p genéricos vivem em theme-dark.css). */
.step-badge {
  background: rgba(93, 195, 240, 0.14);
  color: var(--sky-500);
  box-shadow: none;
}
