/* ==========================================================
   RAFAEL PORTFOLIO — BLACK HOLE 3D CINEMATIC MOTION (v4)
   Camada sobre a identidade já existente do portfólio.
   A fonte exata do No Man's Sky não está disponível para uso
   web; Orbitron continua sendo usada como substituta próxima
   (geométrica, técnica, maiúscula) — igual às versões anteriores.

   O que mudou na v4:
   - O buraco negro em CSS (anéis, lente, núcleo) foi REMOVIDO.
     Agora a tela inicial mostra só o MODELO 3D real
     (black_hole.glb, via Three.js) e o nome — nada mais.
   - O modelo 3D está bem maior (a "singularidade" ocupa boa
     parte da tela, como na referência enviada).
   - A iluminação da cena 3D foi recalibrada para a paleta da
     imagem de referência: disco de acréscimo frio/branco-azulado
     na parte de cima, brilho quente/âmbar por baixo, núcleo
     totalmente preto.
   - Como não existe mais o desenho 2D como fallback visual, se o
     WebGL falhar sobra apenas um brilho circular simples
     (.bh-fallback-glow) na mesma paleta — discreto, sem os anéis.
   - Rolagem (queda até a singularidade, estilo oryzo.ai) e drag
     (desloca + inclina o modelo, apaga o nome) continuam como antes.
   ========================================================== */

:root{
  --bh-white:#f5f3ee;
  --bh-muted:#777771;
  --bh-line:#252525;
  --bh-bg:#000;
  --bh-ease:cubic-bezier(.16,1,.3,1);
  --bh-slow:cubic-bezier(.22,.61,.36,1);
  --bh-spin:1;          /* driven by JS: anéis/​modelo giram mais rápido perto do horizonte */
  --bh-vignette-o:.55;  /* driven by JS: vinheta aprofunda conforme cai */
}

body{
  background:#000;
}

/* ---------- abertura cinemática ---------- */

.bh-intro{
  position:fixed;
  inset:0;
  z-index:10000;
  overflow:hidden;
  background:
    radial-gradient(circle at 50% 48%, rgba(255,255,255,.035), transparent 30%),
    #000;
  color:var(--bh-white);
  isolation:isolate;
  cursor:default;
  transition:
    opacity .9s var(--bh-ease),
    visibility 0s linear .95s;
}

.bh-intro.is-leaving{
  opacity:0;
  visibility:hidden;
  pointer-events:none;
}

/* Wrapper de parallax: recebe transform via JS (drag/scroll).
   O drift automático (bhStarDrift) continua isolado no filho
   .bh-stars, então os dois movimentos não competem pela mesma
   propriedade transform. */
.bh-parallax{
  position:absolute;
  inset:0;
  will-change:transform;
  transition:transform .6s var(--bh-slow);
}

.bh-stars{
  position:absolute;
  inset:-15%;
  opacity:.38;
  background-image:
    radial-gradient(circle at 10% 18%, rgba(255,255,255,.72) 0 1px, transparent 1.4px),
    radial-gradient(circle at 72% 23%, rgba(255,255,255,.5) 0 1px, transparent 1.4px),
    radial-gradient(circle at 32% 76%, rgba(255,255,255,.4) 0 1px, transparent 1.3px),
    radial-gradient(circle at 87% 71%, rgba(255,255,255,.65) 0 1px, transparent 1.4px),
    radial-gradient(circle at 52% 9%, rgba(255,255,255,.45) 0 1px, transparent 1.3px),
    radial-gradient(circle at 18% 51%, rgba(255,255,255,.45) 0 1px, transparent 1.3px);
  background-size:240px 220px, 330px 300px, 280px 260px, 360px 340px, 310px 280px, 420px 380px;
  animation:bhStarDrift 18s linear infinite;
  transform:translate3d(0,0,0);
}

@keyframes bhStarDrift{
  from{transform:translate3d(0,0,0) scale(1.02)}
  to{transform:translate3d(-22px,12px,0) scale(1.05)}
}

.bh-vignette{
  position:absolute;
  inset:0;
  z-index:5;
  pointer-events:none;
  opacity:var(--bh-vignette-o);
  background:
    radial-gradient(circle at 50% 50%, transparent 28%, rgba(0,0,0,.32) 60%, rgba(0,0,0,.92) 100%),
    linear-gradient(180deg,rgba(0,0,0,.55),transparent 30%,transparent 70%,rgba(0,0,0,.65));
}

.bh-system{
  position:absolute;
  left:50%;
  top:50%;
  width:min(82vw,1040px);
  aspect-ratio:1;
  transform:translate(-50%,-50%);
  z-index:2;
  cursor:grab;
  touch-action:none;
  will-change:transform,filter;
}

.bh-system:active{
  cursor:grabbing;
}

.bh-system::before{
  content:"";
  position:absolute;
  inset:5%;
  border-radius:50%;
  background:radial-gradient(circle, rgba(255,255,255,.07), transparent 54%);
  filter:blur(12px);
}

/* ---------- camada 3D (Three.js) — único visual do buraco negro ---------- */

.bh-canvas{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  display:block;
  z-index:2;
  opacity:0;
  transition:opacity 1.2s var(--bh-ease);
}

.bh-intro.bh-3d-ready .bh-canvas{
  opacity:1;
}

.bh-intro.bh-3d-failed .bh-canvas{
  display:none;
}

/* Fallback minimalista para quando o WebGL/​modelo falha: um brilho
   circular só, na mesma paleta da imagem de referência (frio por
   cima, âmbar por baixo, núcleo preto) — sem os anéis desenhados. */
.bh-fallback-glow{
  position:absolute;
  inset:6%;
  border-radius:50%;
  z-index:1;
  display:none;
  background:
    radial-gradient(circle at 50% 50%, rgba(255,255,255,.16), transparent 48%),
    #000;
  box-shadow:
    0 0 60px 10px rgba(255,255,255,.07),
    0 0 120px 30px rgba(255,255,255,.05);
}
.bh-intro.bh-3d-failed .bh-fallback-glow{
  display:block;
}

/* Pontinhos discretos de carregamento — somem quando o modelo
   3D entra ou quando cai no fallback. */
.bh-loading{
  position:absolute;
  left:50%;
  bottom:-42px;
  transform:translateX(-50%);
  display:flex;
  gap:7px;
  z-index:6;
  opacity:1;
  transition:opacity .5s ease;
}
.bh-loading i{
  width:4px;
  height:4px;
  border-radius:50%;
  background:var(--bh-muted);
  animation:bhLoadPulse 1.1s ease-in-out infinite;
}
.bh-loading i:nth-child(2){animation-delay:.15s}
.bh-loading i:nth-child(3){animation-delay:.3s}
@keyframes bhLoadPulse{
  0%,100%{opacity:.25; transform:scale(.85)}
  50%{opacity:1; transform:scale(1.15)}
}
.bh-intro.bh-3d-ready .bh-loading,
.bh-intro.bh-3d-failed .bh-loading{
  opacity:0;
  pointer-events:none;
}

.bh-name{
  position:absolute;
  z-index:7;
  left:50%;
  top:50%;
  transform:translate(-50%,-50%);
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:.02em;
  width:min(90vw,900px);
  color:#fff;
  text-align:center;
  text-transform:uppercase;
  font-family:"Orbitron","Unbounded",sans-serif;
  font-weight:700;
  letter-spacing:.12em;
  line-height:.94;
  font-size:clamp(28px,5.3vw,82px);
  text-shadow:
    0 2px 18px rgba(0,0,0,.85),
    0 0 34px rgba(0,0,0,.7),
    0 0 60px rgba(255,255,255,.1);
  pointer-events:none;
  will-change:transform,opacity,filter;
}

.bh-name span{
  display:block;
  animation:bhNameIn 1.05s var(--bh-ease) both;
}
.bh-name span:nth-child(1){animation-delay:.18s}
.bh-name span:nth-child(2){animation-delay:.28s}
.bh-name span:nth-child(3){animation-delay:.38s}

@keyframes bhNameIn{
  from{
    opacity:0;
    transform:translateY(18px) scale(.97);
    letter-spacing:.28em;
    filter:blur(8px);
  }
  to{
    opacity:1;
    transform:none;
    letter-spacing:.12em;
    filter:blur(0);
  }
}

.bh-meta{
  position:absolute;
  z-index:8;
  left:28px;
  right:28px;
  bottom:28px;
  display:flex;
  justify-content:space-between;
  color:#666661;
  font:10px/1 "JetBrains Mono",monospace;
  letter-spacing:.14em;
  text-transform:uppercase;
}

.bh-scroll-line{
  position:absolute;
  z-index:8;
  left:50%;
  bottom:30px;
  width:1px;
  height:48px;
  background:linear-gradient(to bottom, transparent, rgba(255,255,255,.65));
  transform:translateX(-50%);
  animation:bhScrollPulse 1.8s ease-in-out infinite;
}

.bh-scroll-line i{
  display:block;
  width:1px;
  height:14px;
  background:#fff;
  animation:bhScrollDrop 1.8s ease-in-out infinite;
}

@keyframes bhScrollPulse{
  0%,100%{opacity:.35}
  50%{opacity:1}
}
@keyframes bhScrollDrop{
  0%{transform:translateY(-5px);opacity:0}
  30%{opacity:1}
  70%,100%{transform:translateY(30px);opacity:0}
}

/* Pequeno anel "arraste-me", só visível antes de rolar/interagir,
   para o mecanismo ser descobrível sem texto sobre a identidade. */
.bh-system::after{
  content:"";
  position:absolute;
  inset:-6%;
  border-radius:50%;
  border:1px dashed rgba(255,255,255,.16);
  opacity:0;
  transition:opacity .5s ease;
  pointer-events:none;
}
.bh-intro.is-ready:not(.bh-scrolled):not(.bh-dragging) .bh-system:hover::after{
  opacity:1;
}

/* Enquanto a singularidade é arrastada, o nome recua até quase
   transparente — a identidade cede lugar ao gesto, de propósito. */
.bh-intro.bh-dragging .bh-name{
  transition:opacity .2s ease;
}

/* Flash de luz (criado via JS) que faz a ponte da queda até o
   herói real do portfólio. */
.bh-flash{
  position:absolute;
  inset:0;
  z-index:9;
  pointer-events:none;
  opacity:0;
  background:radial-gradient(circle at 50% 50%, rgba(255,255,255,.95), rgba(255,255,255,0) 62%);
}
.bh-intro.bh-flashing .bh-flash{
  opacity:1;
  transition:opacity .16s ease-out;
}
.bh-intro.bh-flashing.is-leaving .bh-flash{
  opacity:0;
  transition:opacity .85s ease .05s;
}

/* Onda de choque (criada via JS): um anel que se expande a partir
   do buraco negro no instante da liberação, reforçando a sensação
   de que o conteúdo seguinte foi chutado para fora dele. */
.bh-shock{
  position:absolute;
  left:50%;
  top:48%;
  width:10px;
  height:10px;
  border-radius:50%;
  border:1.5px solid rgba(255,255,255,.7);
  transform:translate(-50%,-50%);
  opacity:0;
  pointer-events:none;
  z-index:9;
}
.bh-intro.bh-shocking .bh-shock{
  animation:bhShockOut .95s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes bhShockOut{
  0%{width:8px; height:8px; opacity:.85; border-width:2.5px;}
  55%{opacity:.4;}
  100%{width:240vmax; height:240vmax; opacity:0; border-width:0;}
}

/* Estado de rolagem: o nome cai em direção à singularidade enquanto
   o buraco negro se expande, revelando o herói real do portfólio.
   Os valores de transform/filter de .bh-system e .bh-name são
   controlados continuamente via JS (ver blackhole.js) para um zoom
   suave e não escalonado; estas regras data-progress cobrem só o
   que é barato/robusto de fazer em CSS puro. */

.bh-intro[data-progress="2"] .bh-meta,
.bh-intro[data-progress="2"] .bh-scroll-line{
  opacity:0;
  transform:translate(-50%,14px);
}

/* ---------- transforma o portfólio existente no destino ---------- */

body.bh-locked{
  overflow:hidden;
}

/* Cabeçalho e rodapé entram com um fade simples — o "estouro" fica
   reservado só para o herói, que é o que nasce do buraco negro. */
body.bh-entering header,
body.bh-entering footer{
  opacity:0;
}
body.bh-ready header,
body.bh-ready footer{
  opacity:1;
  transition:opacity .8s var(--bh-ease) .15s;
}

body.bh-entering main{
  opacity:0;
}
body.bh-ready main{
  opacity:1;
  transition:opacity .5s linear;
}

/* O herói nasce comprimido, girado e borrado exatamente no ponto
   onde estava a singularidade — como se tivesse sido chutado para
   fora do buraco negro — e se desfaz da distorção ao se acomodar
   no lugar normal, com um leve exagero elástico no final. */
body.bh-entering #inicio .hero{
  opacity:0;
  transform:scale(.24) rotate(-7deg);
  filter:blur(20px) brightness(1.7) saturate(1.3);
  clip-path:circle(0% at 50% 42%);
}
body.bh-ready #inicio .hero{
  opacity:1;
  transform:none;
  filter:blur(0) brightness(1) saturate(1);
  clip-path:circle(150% at 50% 42%);
  transition:
    opacity .6s var(--bh-ease),
    transform 1.2s cubic-bezier(.2,1.4,.3,1),
    filter 1s var(--bh-ease),
    clip-path 1.1s var(--bh-ease) .05s;
}

/* Substitui visualmente o antigo herói de duas colunas após a
   abertura. O conteúdo existente continua intacto e vira a
   identidade do portfólio. */
body.bh-ready #inicio{
  transition:padding-top .9s var(--bh-ease);
}

body.bh-ready #inicio .hero{
  transform:translateY(calc(var(--bh-hero-y, 0px)));
  transition:transform 1s var(--bh-ease);
}

/* Reforça o momento de "pouso" no primeiro título real. */
body.bh-ready #inicio h1{
  text-shadow:0 0 40px rgba(255,255,255,.06);
}

/* Mantém compatível a tecnologia visual de buraco negro já usada
   em outras partes do site. */
.black-hole{
  position:absolute;
  left:50%;
  top:50%;
  width:82px;
  height:82px;
  transform:translate(-50%,-50%);
  border-radius:50%;
  z-index:5;
  pointer-events:none;
}
.black-hole-core{
  position:absolute;
  inset:18%;
  border-radius:50%;
  background:#000;
  box-shadow:0 0 24px 8px rgba(0,0,0,.9);
}
.black-hole-glow{
  position:absolute;
  inset:-18%;
  border-radius:50%;
  background:radial-gradient(circle,rgba(255,255,255,.08),transparent 68%);
  filter:blur(6px);
}
.black-hole-ring{
  position:absolute;
  left:50%;
  top:50%;
  border:1px solid rgba(255,255,255,.22);
  border-radius:50%;
  transform:translate(-50%,-50%);
}
.black-hole-ring.ring-1{
  width:125%;
  height:46%;
  transform:translate(-50%,-50%) rotate(-18deg);
}
.black-hole-ring.ring-2{
  width:155%;
  height:58%;
  transform:translate(-50%,-50%) rotate(24deg);
  opacity:.65;
}
.black-hole-ring.ring-3{
  width:185%;
  height:70%;
  transform:translate(-50%,-50%) rotate(-36deg);
  opacity:.35;
}

/* ---------- responsivo ---------- */

@media (max-width:760px){
  .bh-system{
    width:min(92vw,520px);
    top:46%;
  }

  .bh-name{
    font-size:clamp(24px,8.5vw,52px);
    letter-spacing:.08em;
  }

  .bh-meta{
    left:18px;
    right:18px;
    bottom:20px;
    font-size:8px;
  }

  .bh-meta span:first-child{
    display:none;
  }

  .bh-scroll-line{
    bottom:20px;
  }
}

@media (prefers-reduced-motion:reduce){
  .bh-stars,
  .bh-scroll-line,
  .bh-scroll-line i,
  .bh-name span,
  .bh-loading i,
  .bh-shock{
    animation:none !important;
  }

  .bh-intro,
  .bh-system,
  .bh-parallax,
  .bh-name,
  .bh-meta,
  .bh-flash,
  .bh-shock,
  .bh-canvas{
    transition:none !important;
  }

  /* Sem o "estouro" para fora do buraco negro: o herói aparece
     direto, no lugar e sem distorção. */
  body.bh-entering #inicio .hero,
  body.bh-ready #inicio .hero{
    opacity:1 !important;
    transform:none !important;
    filter:none !important;
    clip-path:none !important;
    transition:none !important;
  }

  /* Com movimento reduzido, nem tentamos o WebGL: fica só o brilho
     estático de fallback, na paleta da referência. */
  .bh-canvas{
    display:none;
  }
  .bh-fallback-glow{
    display:block;
  }
}
