/* ===== Splash de carregamento — o que se vê antes da cena SLAM existir =====
 *
 * Portado da 2026.5 (`css/base.css`), onde nasceu, com as mesmas medidas: o
 * robô do cartão impresso, três anéis saindo de trás dele, a marca e uma barra
 * indeterminada.
 *
 * ⚠️ TUDO anima por `transform` e `opacity`, e isso não é preferência de estilo.
 * São as duas propriedades que o compositor anima sozinho, sem passar pela
 * thread principal — que é exatamente a thread que o boot do Three.js bloqueia.
 * Qualquer animação de `width`, `top` ou `filter` aqui congelaria junto com a
 * cena, e um carregando congelado é pior que nenhum: parece travado.
 *
 * Fica em arquivo próprio de propósito: as nove fatias `lab-*.css` são um corte
 * por faixa contígua do antigo `lab.css`, e `task css:verify` prova que elas o
 * remontam byte a byte. Acrescentar uma regra a qualquer uma quebraria a prova.
 */

.boot {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(ellipse at center,
      rgba(8, 14, 34, .96) 0%,
      rgba(2, 4, 10, .995) 55%,
      #02040a 100%);
  cursor: pointer;
  transition: opacity 1.1s cubic-bezier(.22, 1, .36, 1),
              filter   1.1s cubic-bezier(.22, 1, .36, 1);
  will-change: opacity, filter;
}

/* `visibility` junto com `opacity`: só a opacidade deixaria o overlay
   interceptando clique durante a transição inteira. */
.boot.hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  filter: blur(6px);
}

.boot-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 17px;
  transform: translateZ(0);
}

.boot-art {
  position: relative;
  display: grid;
  place-items: center;
  width: 260px;
  height: 260px;
  margin-bottom: 2px;
}

/* Halo por trás de tudo: dá volume ao recorte do robô, que é PNG com alpha e sem
   ele fica colado no fundo chapado. */
.boot-art::before {
  content: '';
  position: absolute;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(42, 92, 255, .38) 0%, rgba(42, 92, 255, .10) 45%, transparent 70%);
  animation: boot-halo 2.6s ease-in-out infinite;
  will-change: transform, opacity;
}

.boot-art img {
  position: relative;
  z-index: 2;
  width: 212px;
  height: auto;
  filter: drop-shadow(0 18px 34px rgba(0, 0, 0, .62))
          drop-shadow(0 0 30px rgba(42, 92, 255, .42));
  /* Entra com escala: o splash aparece no primeiro quadro e o robô "chega" nele,
     em vez de já estar posto. */
  animation: boot-enter .7s cubic-bezier(.16, 1, .3, 1) both,
             boot-float 3.1s ease-in-out .7s infinite;
  will-change: transform;
}

/* Três anéis com o MESMO keyframe e atrasos diferentes: a onda parece contínua
   sem custar três animações distintas. */
.boot-ring {
  position: absolute;
  width: 168px;
  height: 168px;
  border: 1px solid rgba(111, 214, 255, .55);
  border-radius: 50%;
  box-shadow: 0 0 18px rgba(111, 214, 255, .22);
  animation: boot-wave 1.9s cubic-bezier(.22, .8, .3, 1) infinite;
  will-change: transform, opacity;
}
.boot-ring:nth-of-type(2) { animation-delay: .63s; }
.boot-ring:nth-of-type(3) { animation-delay: 1.26s; }

.boot-mark {
  font-size: 38px;
  line-height: 1;
  color: var(--accent, #6fd6ff);
  text-shadow: 0 0 22px rgba(111, 214, 255, .55);
  animation: boot-pulse 1.9s ease-in-out infinite;
  will-change: transform, opacity;
}

.boot-name {
  font: 600 12.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
  letter-spacing: .42em;
  /* O `text-indent` compensa o espaço que o último caractere ganha do
     `letter-spacing` — sem ele a palavra fica visivelmente fora do centro. */
  text-indent: .42em;
  color: #9cc0f0;
  opacity: .9;
  animation: boot-fade 1.9s ease-in-out infinite;
}

/* Barra INDETERMINADA, não uma barra de progresso: não há progresso a informar —
   o boot do Three.js não expõe fração nenhuma, e uma barra que finge medir
   mente. Esta só diz "está acontecendo". */
.boot-bar {
  width: min(210px, 50vw);
  height: 2px;
  margin-top: 2px;
  border-radius: 2px;
  overflow: hidden;
  background: rgba(111, 214, 255, .12);
}
.boot-bar > i {
  display: block;
  width: 42%;
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--accent, #6fd6ff) 50%, transparent);
  box-shadow: 0 0 12px rgba(111, 214, 255, .6);
  transform: translateX(-130%);
  animation: boot-slide 1.25s cubic-bezier(.45, 0, .25, 1) infinite;
  will-change: transform;
}

/* 3,1 s do robô contra 1,9 s dos anéis e 2,6 s do halo: períodos que não são
   múltiplos, para o conjunto não sincronizar e virar uma pulsação só. */
@keyframes boot-enter {
  from { transform: scale(.82) translateY(14px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@keyframes boot-float { 50% { transform: translateY(-10px) rotate(-1.8deg); } }
@keyframes boot-halo  { 50% { transform: scale(1.14); opacity: .72; } }
@keyframes boot-wave {
  0%   { transform: scale(.58); opacity: 0; }
  18%  { opacity: .9; }
  100% { transform: scale(1.7); opacity: 0; }
}
@keyframes boot-pulse {
  0%, 100% { transform: scale(.94); opacity: .7; }
  50%      { transform: scale(1.12); opacity: 1; }
}
@keyframes boot-fade {
  0%, 100% { opacity: .55; }
  50%      { opacity: .95; }
}
@keyframes boot-slide {
  0%   { transform: translateX(-130%); }
  100% { transform: translateX(335%); }
}

/* Telas baixas (telefone deitado): o robô sai e sobra a marca, que já bastava
   antes de ele existir. */
@media (max-height: 620px) {
  .boot-art { display: none; }
}

/* Quem pediu menos movimento continua vendo o splash — ele informa —, só que
   parado. `animation-iteration-count` é o que de fato encerra o laço: duração
   curta apenas o acelera, e 12 animações infinitas a 60 Hz é trabalho de
   composição por nada, justamente na máquina que pediu menos. */
@media (prefers-reduced-motion: reduce) {
  .boot,
  .boot *,
  .boot *::before {
    animation-iteration-count: 1 !important;
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}
