/* Home hero — reforços visuais.
   ============================================================

   Carregado SÓ pela home (livewire/home.blade.php, via @push('head')),
   nunca pelas outras 25 páginas que usam <x-hero-section> — ver o
   cabeçalho de public/css/fundador.css para a razão do @push('head') em
   vez de um <style> no componente Livewire: a extracção de estilos do
   Livewire 4 não injecta o <link>, a página fica sem uma única regra
   deste ficheiro sem erro nenhum. Um <link> normal escapa a esse
   problema por completo.

   Toda a folha está sob o selector `.hero-home`, que <x-hero-section
   variant="home"> é o ÚNICO chamador a pedir (ver o @props do
   componente). Mesmo que este ficheiro fosse por engano carregado
   nalguma outra página, não bateria em nada — dupla segurança, a par
   do @push('head') scoped à home.

   2026-08-29 (Patrícia, a pedido do Paulo): a hero tinha uma dúzia de
   classes — .scanlines, .vhs-tracking, .pixel-noise, .retro-loading,
   .retro-grid, .crt-screen, .startup-animation, .spectrum-colors,
   .pixel-border, .cube3d/.sphere3d/.triangle3d, .spectrum-loading —
   escritas no markup mas NUNCA definidas em CSS nenhum lado do
   repositório. A "estética retro/terminal" da hero, tal como estava,
   era: fundo preto, uma linha verde, o glitch do h1 (esse sim
   definido, globalmente, em site.blade.php) e um botão com border-2
   normal. O resto — scanlines, ruído, grelha, barra de loading, as 12
   formas 3D com parallax de rato JÁ ligado em JS — não renderizava
   nada. Este ficheiro acende essas classes, mas nem todas: ficaram de
   fora .vhs-tracking e .pixel-noise (ver nota mais abaixo) para não
   empilhar textura em cima de textura sobre um bloco de texto que tem
   de continuar legível. */


/* --- Entrada em sequência ("boot") -------------------------------
   Uma vez, ao carregar — não em loop. Atrasos pequenos (≤240ms) de
   propósito: o h1 costuma ser o elemento do LCP, e opacity:0 atrasa o
   instante em que o Chrome o conta como "pintado" para efeitos de LCP.
   Isto não é um efeito de "impressionar", é reforçar a ideia de
   diagnóstico/arranque que o terminalText já sugere ("MAPPING THE
   PROCESS...") sem custar performance percebida.

   .hero-stagger-2 (o h1) só anima opacity, nunca transform: o h1 já
   tem .glitch-text a animar `transform` (skew) para sempre — duas
   animações a mexer na mesma propriedade no mesmo elemento têm
   comportamento de composição ambíguo entre motores, por isso aqui só
   uma delas toca em transform. */
.hero-home .hero-stagger-1,
.hero-home .hero-stagger-2,
.hero-home .hero-stagger-3,
.hero-home .hero-stagger-4 {
  opacity: 0;
  animation-duration: .5s;
  animation-timing-function: cubic-bezier(.16, .8, .3, 1);
  animation-fill-mode: both;
}

.hero-home .hero-stagger-1 { animation-name: hero-stagger-in;   animation-delay: 0s; }
.hero-home .hero-stagger-2 { animation-name: hero-stagger-fade; animation-delay: .08s; }
.hero-home .hero-stagger-3 { animation-name: hero-stagger-in;   animation-delay: .16s; }
.hero-home .hero-stagger-4 { animation-name: hero-stagger-in;   animation-delay: .24s; }

@keyframes hero-stagger-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes hero-stagger-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}


/* --- Cursor do terminal --------------------------------------------
   `currentColor` apanha o verde (#33ff33) que a div já tem via
   Tailwind — não precisa de repetir a cor aqui. */
.hero-home .terminal-text::after {
  content: '';
  display: inline-block;
  width: .5em;
  height: 1em;
  margin-left: .3em;
  background: currentColor;
  vertical-align: -0.15em;
  animation: hero-cursor-blink 1s steps(1, end) infinite;
}

@keyframes hero-cursor-blink {
  0%, 49%  { opacity: 1; }
  50%, 100% { opacity: 0; }
}


/* --- Barra de "boot" -------------------------------------------------
   A div .retro-loading já existia (absolute, top-0, z-20) só sem
   altura nem fundo — por isso não pintava nada. `scaleX` em vez de
   largura: escala é transform, não obriga a layout a cada frame.
   Cores = o mesmo gradiente "spectrum" do blob SVG à direita da hero
   (mesmos 5 stops), para a barra e o blob lerem como o mesmo motivo em
   vez de dois efeitos a competir. */
.hero-home .retro-loading {
  height: 3px;
  background: linear-gradient(90deg, #0000d8 0%, #d80000 25%, #00d800 50%, #d8d800 75%, #F2F2F2 100%);
  transform: scaleX(0);
  transform-origin: 0 50%;
  animation: hero-loading-fill .9s .1s cubic-bezier(.16, .8, .3, 1) both;
}

@keyframes hero-loading-fill {
  to { transform: scaleX(1); }
}


/* --- Grelha de fundo -------------------------------------------------
   A div .retro-grid já tinha opacity-10 no markup (Tailwind) — só
   faltava a imagem. Linhas de 40px, mascaradas para se desvanecerem
   nos bordos em vez de cobrirem o rectângulo todo: o motivo é
   "mapear", não "papel quadriculado". Estática de propósito — uma
   grelha a andar não acrescenta nada e o orçamento de movimento desta
   hero já vai na barra de loading + cursor + entrada + formas. */
.hero-home .retro-grid {
  background-image:
    linear-gradient(rgba(242, 242, 242, .5) 1px, transparent 1px),
    linear-gradient(90deg, rgba(242, 242, 242, .5) 1px, transparent 1px);
  background-size: 40px 40px;
  background-position: center top;
  -webkit-mask-image: radial-gradient(ellipse 85% 65% at 50% 25%, #000 35%, transparent 88%);
          mask-image: radial-gradient(ellipse 85% 65% at 50% 25%, #000 35%, transparent 88%);
}


/* --- Textura de varrimento --------------------------------------------
   A div .scanlines fica com uma textura fina e estática (sem
   animação: é ruído de ecrã, não sinal em movimento). As irmãs
   .vhs-tracking e .pixel-noise ficam SEM CSS de propósito — grelha +
   scanlines + as formas 3D + o glitch do h1 já dão à hero mais
   textura do que a maioria das páginas do site; uma quarta e quinta
   camada de ruído por cima do texto começava a prejudicar a leitura
   em vez de ajudar. */
.hero-home .scanlines {
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, .3)  0,
    rgba(0, 0, 0, .3)  1px,
    transparent        1px,
    transparent         3px
  );
  opacity: .5;
}


/* --- Formas 3D flutuantes ----------------------------------------------
   Os 12 <div> gerados pelo Alpine (hero3d(), no próprio componente) já
   respondem a rato e scroll — a lógica de parallax sempre esteve
   ligada. Só não tinham CSS nenhum: sem `position`, o left/top vw/vh
   inline não fazia nada, e sem fundo/borda eram invisíveis mesmo que
   posicionados. Dá-se-lhes um contorno translúcido (não preenchido:
   "wireframe", coerente com o nome "3D retro elements" do comentário
   original) nas duas cores do glitch do h1 (#00fff9 ciano, #ff00c1
   magenta) mais o verde do terminal — as MESMAS três cores já usadas
   no resto da hero, em vez de introduzir uma paleta nova.

   `translate` (propriedade independente, não o `transform` shorthand)
   para o flutuar: o inline style de cada forma já usa `transform:
   rotateZ()` estático (rotação aleatória por forma, calculada em JS) —
   animar `transform` aqui apagaria essa rotação enquanto a animação
   corre. `translate` anima em paralelo sem pisar o `transform`, e
   como as duas fazem parte da mesma família de propriedades
   compostas pelo GPU, o custo é o mesmo que animar transform. */
.hero-home .cube3d,
.hero-home .sphere3d,
.hero-home .triangle3d {
  position: absolute;
  animation-name: hero-shape-float;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  /* duration/delay vêm do atributo style inline (aleatórios, por forma) */
}

@keyframes hero-shape-float {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -18px; }
}

.hero-home .cube3d {
  border: 1.5px solid rgba(0, 255, 249, .35);
  background: linear-gradient(135deg, rgba(0, 255, 249, .10), transparent 60%);
  border-radius: 4px;
}

.hero-home .sphere3d {
  border: 1.5px solid rgba(255, 0, 193, .35);
  background: radial-gradient(circle at 35% 30%, rgba(255, 0, 193, .14), transparent 65%);
  border-radius: 50%;
}

.hero-home .triangle3d {
  background: linear-gradient(160deg, rgba(51, 255, 51, .18), transparent 70%);
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

/* As faces front/back/right/left/top/bottom (markup preparado para um
   cubo 3D "a sério" com preserve-3d por face) nunca tiveram
   posicionamento próprio nem no JS nem em CSS nenhum — sem inventar
   6 transforms por forma às cegas, ficam ocultas e a forma exterior
   (acima) é que carrega o efeito. */
.hero-home .cube3d > div,
.hero-home .sphere3d > div,
.hero-home .triangle3d > div {
  display: none;
}

/* Os 3 blobs de parallax (x-ref="parallax1/2/3", already movidos por
   JS em cada mousemove/scroll) só precisavam de um preenchimento — a
   opacity-10/15/20 já vem do Tailwind no markup. Gradiente cónico com
   as mesmas 5 cores do blob SVG e da barra de loading: um único
   motivo "spectrum", não um quarto efeito à parte. */
.hero-home .spectrum-loading {
  background: conic-gradient(from 0deg, #0000d8, #d80000, #00d800, #d8d800, #F2F2F2, #0000d8);
  filter: blur(1px);
}


/* --- Botão principal — moldura em "pixel corners" -----------------------
   A âncora já tinha a classe .pixel-border sem efeito nenhum: era um
   border-2 normal por baixo. Este é o CTA que empurra para a landing
   — o único botão da hero — por isso ganha peso a mais.

   A moldura vive num ::before, NUNCA num clip-path na própria âncora:
   clip-path recorta também o outline de :focus-visible se estiver no
   mesmo elemento (é um erro fácil de cometer nesta técnica). Com o
   clip-path isolado no pseudo-elemento, o focus ring da âncora sai
   sempre inteiro. */
.hero-home .pixel-border {
  position: relative;
  isolation: isolate;
}

.hero-home .pixel-border::before {
  content: '';
  position: absolute;
  inset: -7px;
  z-index: -1;
  clip-path: polygon(
    0 10px, 10px 10px, 10px 0,
    calc(100% - 10px) 0, calc(100% - 10px) 10px, 100% 10px,
    100% calc(100% - 10px), calc(100% - 10px) calc(100% - 10px), calc(100% - 10px) 100%,
    10px 100%, 10px calc(100% - 10px), 0 calc(100% - 10px)
  );
  background: linear-gradient(135deg, #33ff33, #00fff9 45%, #ff00c1 100%);
  opacity: .55;
  transform: translate(0, 0);
  transition: opacity .2s ease, transform .2s ease;
  pointer-events: none;
}

.hero-home .pixel-border:hover::before,
.hero-home .pixel-border:focus-visible::before {
  opacity: .9;
  transform: translate(3px, 3px);
}

.hero-home .pixel-border:active::before {
  transform: translate(1px, 1px);
}

/* Focus ring próprio: verde do terminal sobre fundo preto (contraste
   altíssimo), com offset suficiente para não se confundir com a
   moldura pixelada acima. */
.hero-home .pixel-border:focus-visible {
  outline: 2px solid #33ff33;
  outline-offset: 6px;
}


/* --- prefers-reduced-motion --------------------------------------------
   Cobre tudo o que este ficheiro anima, MAIS o glitch do h1 — que é
   global (site.blade.php) e nunca respeitou reduced-motion em página
   nenhuma. Não se toca no ficheiro global (arriscava as outras 25
   páginas); aqui o selector `.hero-home .glitch-text` tem mais
   especificidade (2 classes) do que o `.glitch-text` sozinho lá
   fora (1 classe), por isso ganha só na home, sem mexer em mais nada.
   As outras 25 páginas mantêm o comportamento actual (fora do âmbito
   desta corrida — sinalizado ao Paulo, não corrigido aqui). */
@media (prefers-reduced-motion: reduce) {
  .hero-home .hero-stagger-1,
  .hero-home .hero-stagger-2,
  .hero-home .hero-stagger-3,
  .hero-home .hero-stagger-4 {
    opacity: 1;
    animation: none;
    transform: none;
  }

  .hero-home .terminal-text::after {
    animation: none;
    opacity: 1;
  }

  .hero-home .retro-loading {
    animation: none;
    transform: scaleX(1);
  }

  .hero-home .cube3d,
  .hero-home .sphere3d,
  .hero-home .triangle3d {
    animation: none;
  }

  .hero-home .glitch-text,
  .hero-home .glitch-text::before,
  .hero-home .glitch-text::after {
    animation: none;
    transform: none;
  }

  .hero-home .pixel-border::before {
    transition: none;
  }
}


/* ============================================================
 * Bloco "DIGITALDEV" gigante, entre a hero e #services.
 * ============================================================
 *
 * Substitui o par de hacks que aqui estava: no mobile, o bloco vivia
 * em position:absolute + top:50% + translate + um "top:-27px" de
 * afinação; a partir de lg, mudava para position:static + margin:
 * -160px. As duas regras viviam num selector global perigoso em
 * site.blade.php — `.relative.z-10 div { ... }` — que bate em
 * QUALQUER <div> descendente de QUALQUER elemento com as classes
 * "relative" e "z-10" ao mesmo tempo, em qualquer página. Na prática
 * só a home o disparava (o mesmo bloco existe, comentado, em
 * blog.blade.php e blog/post.blade.php) — mas era só sorte, não
 * garantia nenhuma.
 *
 * Esta versão não usa "relative z-10" no wrapper (deixa de disparar
 * essa regra global — não se tocou em site.blade.php, ficou lá morta
 * como sempre esteve para as outras páginas) e substitui os dois
 * hacks por UMA fórmula contínua (clamp) para tamanho e para a
 * margem negativa, válida em todas as larguras — sem saltos nos
 * breakpoints, que era exactamente a suspeita do Paulo.
 *
 * A margem negativa tem de ficar ligada ao próprio tamanho do texto,
 * não escolhida ao acaso: o "DIGITALDEV" tem o preenchimento cortado
 * a meio (metade branco, metade preto, via background-clip:text) — o
 * efeito só lê bem se esse corte a meio calhar aproximadamente na
 * costura entre o preto da hero e o #F2F2F2 da secção #services a
 * seguir. Por isso a margem é sensivelmente metade da altura do
 * texto (que por sua vez é ~0.85× o font-size, com este line-height).
 *
 * O tecto da margem está limitado a -5rem (80px): é exactamente o
 * pb-20 (padding preto vazio) que a hero deixa a seguir aos botões —
 * o texto nunca sobe mais do que isso, logo nunca alcança o botão
 * "Ver como trabalhamos" nem nada clicável, em nenhuma largura.
 */
/* A marca "DIGITALDEV" fica a cavalo da fronteira entre o bloco escuro e a
   secção #services (clara): a metade de cima é branca (lê-se sobre o preto),
   a de baixo é preta (lê-se sobre o claro).

   Duas tentativas falharam antes desta, ambas por medir a fronteira errada:
   1) `margin-top` negativo + gradiente fixo a 50% — só concordavam a 1440px;
   2) corte alinhado com o fim da <section> da hero — mas o preto NÃO acaba aí:
      medido no browser a 1920px, a hero fecha a y=1033 e o fundo escuro só dá
      lugar ao cinzento a y≈1275, quando começa o #services. O texto ficava
      inteiro dentro do preto e a metade inferior desaparecia.

   A fronteira que conta é o TOPO do #services. Por isso o bloco desce com
   `margin-bottom` negativo de metade da sua própria altura: o #services sobe
   essa distância e o corte cai exactamente a meio do texto, em qualquer
   largura. O gradiente volta a 50% porque agora 50% é, de facto, a fronteira.

   `--brand-size` é a única medida; altura = size × line-height (.85). */
.home-brand-mark-wrap {
  --brand-size: clamp(3rem, 17vw, 20rem);
  --brand-height: calc(var(--brand-size) * .85);

  position: relative;
  z-index: 1;
  margin-top: 0;
  margin-bottom: calc(var(--brand-height) / -2);
}

.home-brand-mark {
  margin: 0;
  font-size: var(--brand-size);
  line-height: .85;
  letter-spacing: -.05em;
  font-family: sans-serif;
  background: linear-gradient(to bottom, #ffffff 50%, #000000 50%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  color: transparent;
}
