/*
  Site institucional do iFLUXO — a página.

  O cenário noturno vive em `cenario.css` e `cenario.js`, que são um
  conjunto à parte e reutilizável. Esta folha cuida só do que é desta
  página: cabeçalho, composição da marca, tipografia e o indicador de
  trabalho em curso.

  Sobre a marca: os arquivos oficiais em `web/public/` vêm sobre fundo
  preto, e a forma clássica de dissolvê-lo é `mix-blend-mode: screen`.
  Não é o que fazemos — a mistura se perde ao primeiro `transform`,
  `filter` ou `z-index` numa camada acima, e numa página de parallax
  isso é um alçapão. `coruja.png` e `marca.png` são as mesmas artes com
  transparência real, geradas dos arquivos oficiais.
*/

:root {
  --roxo: #7c3aed;
  --roxo-claro: #a78bfa;
  --magenta: #ec4899;
  --texto: #f5f5f7;
  --texto-fraco: #9a98a8;

  --fonte: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, sans-serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  height: 100%;
  /* `clip` e não `hidden`: corta o excesso sem criar um contexto de
     rolagem, que quebraria o `position: fixed` do cenário. */
  overflow-x: clip;
}

body {
  margin: 0;
  min-height: 100svh;
  display: grid;
  /* Cabeçalho no topo, palco ocupando o resto. O palco se centra
     dentro do que sobra, e não da tela inteira — é o que evita o vão
     entre o cabeçalho e a marca no celular. */
  grid-template-rows: auto 1fr;
  background: #05040a;
  color: var(--texto);
  font-family: var(--fonte);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

picture {
  display: block;
}

picture > img {
  display: block;
  width: 100%;
  height: auto;
}

/* ==================================================== cabeçalho */

.cabecalho {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  /* `env()` mantém o conteúdo fora do recorte de tela dos aparelhos. */
  padding: calc(18px + env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) 14px
    max(20px, env(safe-area-inset-left));
  animation: descer 800ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.marca-topo {
  width: clamp(104px, 12vw, 170px);
}

.selo {
  flex: none;
  padding: 8px 18px;
  border: 1px solid rgba(167, 139, 250, 0.45);
  border-radius: 999px;
  font-size: clamp(9.5px, 0.45vw + 8px, 11.5px);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  text-transform: uppercase;
  color: var(--texto);
  background: rgba(124, 58, 237, 0.08);
  transition:
    border-color 300ms ease,
    background 300ms ease,
    box-shadow 300ms ease;
  animation: pulsar-selo 4.5s ease-in-out infinite;
}

.selo:hover {
  border-color: rgba(196, 164, 255, 0.85);
  background: rgba(124, 58, 237, 0.18);
  box-shadow: 0 0 34px -6px rgba(139, 92, 246, 0.95);
}

@keyframes pulsar-selo {
  0%,
  100% {
    box-shadow: 0 0 22px -10px rgba(139, 92, 246, 0.7);
  }
  50% {
    box-shadow: 0 0 30px -6px rgba(139, 92, 246, 0.95);
  }
}

/* ======================================================== palco */

.palco {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(12px, 2vh, 24px);
  padding: 0 max(20px, env(safe-area-inset-left))
    calc(clamp(24px, 6vh, 64px) + env(safe-area-inset-bottom))
    max(20px, env(safe-area-inset-right));
  text-align: center;
  /* O primeiro plano não acompanha o cursor. Ele carrega texto, e texto
     deslocado por fração de pixel a cada quadro é redesenhado borrado —
     além de dar a impressão de que a página escorrega debaixo do mouse.
     A profundidade fica por conta do fundo: `.halo` e `.camada`, que são
     gradiente e SVG, onde o mesmo deslocamento não tem o que estragar. */
}

.marca {
  margin: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(4px, 1vh, 12px);
}

/* O brilho é um irmão atrás da imagem, e não um `filter` nela: um halo
   atrás da arte acende o ar em volta, enquanto um filtro só engrossaria
   a borda. */
.brilho-marca {
  position: absolute;
  top: 36%;
  left: 50%;
  width: min(74vmin, 560px);
  aspect-ratio: 1;
  translate: -50% -50%;
  background: radial-gradient(
    circle,
    rgba(167, 139, 250, 0.3) 0%,
    rgba(124, 58, 237, 0.12) 42%,
    transparent 66%
  );
  animation: brilhar 7s ease-in-out infinite;
}

@keyframes brilhar {
  0%,
  100% {
    opacity: 0.7;
  }
  50% {
    opacity: 1;
  }
}

.coruja {
  position: relative;
  width: clamp(122px, 25vmin, 280px);
  animation: surgir 1000ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.assinatura {
  position: relative;
  width: clamp(180px, 36vmin, 410px);
  animation: surgir 1000ms cubic-bezier(0.22, 1, 0.36, 1) 120ms both;
}

/* A frase, entre dois traços, como na identidade. */
.frase {
  display: flex;
  align-items: center;
  gap: clamp(10px, 2vw, 20px);
  margin: 0;
  font-size: clamp(10.5px, 0.65vw + 8px, 14.5px);
  font-weight: 600;
  letter-spacing: 0.38em;
  text-indent: 0.38em;
  text-transform: uppercase;
  animation: surgir 1000ms cubic-bezier(0.22, 1, 0.36, 1) 260ms both;
}

.frase span {
  background: linear-gradient(95deg, var(--roxo-claro), var(--magenta));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.frase::before,
.frase::after {
  content: '';
  width: clamp(20px, 5vw, 56px);
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(167, 139, 250, 0.75));
}

.frase::after {
  background: linear-gradient(90deg, rgba(167, 139, 250, 0.75), transparent);
}

.risco {
  width: min(44vw, 360px);
  height: 1px;
  margin: 0;
  border: 0;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(139, 92, 246, 0.6) 35%,
    rgba(236, 72, 153, 0.55) 65%,
    transparent
  );
  animation: surgir 1000ms cubic-bezier(0.22, 1, 0.36, 1) 360ms both;
}

.titulo {
  margin: 0;
  /* Sem `max-width`: onde cabe, "EM DESENVOLVIMENTO" fica numa linha
     só, que é como a marca se apresenta. Quando não cabe, `balance`
     reparte as duas em vez de deixar "EM" sozinho em cima. */
  text-wrap: balance;
  font-size: clamp(26px, 6.2vw, 72px);
  font-weight: 800;
  letter-spacing: clamp(0.03em, 0.7vw, 0.11em);
  text-indent: clamp(0.03em, 0.7vw, 0.11em);
  text-transform: uppercase;
  line-height: 1.06;
  /* Dois halos de intensidade diferente: o de perto define a letra, o
     de longe põe a luz no ar em volta dela. */
  text-shadow:
    0 0 18px rgba(167, 139, 250, 0.45),
    0 0 62px rgba(124, 58, 237, 0.4);
  animation:
    surgir 1000ms cubic-bezier(0.22, 1, 0.36, 1) 440ms both,
    neon 6s ease-in-out 1.5s infinite;
}

@keyframes neon {
  0%,
  100% {
    text-shadow:
      0 0 18px rgba(167, 139, 250, 0.4),
      0 0 62px rgba(124, 58, 237, 0.34);
  }
  50% {
    text-shadow:
      0 0 22px rgba(167, 139, 250, 0.58),
      0 0 78px rgba(124, 58, 237, 0.5);
  }
}

.recado {
  margin: 0;
  max-width: min(44ch, 92vw);
  font-size: clamp(11.5px, 0.85vw + 9px, 15.5px);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-indent: 0.18em;
  text-transform: uppercase;
  line-height: 1.9;
  color: var(--texto-fraco);
  animation: surgir 1000ms cubic-bezier(0.22, 1, 0.36, 1) 580ms both;
}

.recado span {
  display: block;
}

@keyframes surgir {
  from {
    opacity: 0;
    translate: 0 18px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

@keyframes descer {
  from {
    opacity: 0;
    translate: 0 -14px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

/* ============================================ energia em curso */

/*
  O indicador de trabalho em andamento.

  Não mede nada, e isso é deliberado: sem percentual, sem etapas, sem
  estado de conclusão. Uma barra que chega a 100% promete uma data, e
  não há data a prometer.

  O que ele faz é mostrar energia percorrendo um trilho, para sempre. O
  núcleo acelera na saída e desacelera na chegada, as faíscas pulsam
  fora de compasso com ele, e nada aqui depende de JavaScript.
*/
/*
  Um apoio escuro atrás do indicador. Não é cartão: é só o fundo
  recuando um pouco onde o texto passa por cima dos prédios iluminados,
  com gradiente radial em vez de caixa — assim não há borda nem canto
  que marque um retângulo na cena.
*/
.energia::before {
  content: '';
  position: absolute;
  /* Em pixels, não em porcentagem: a 320px uma margem relativa
     passava da borda da tela e criava rolagem lateral. */
  inset: -22px -16px;
  background: radial-gradient(60% 100% at 50% 50%, rgba(5, 4, 10, 0.72), transparent 72%);
}

.energia {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(10px, 1.6vh, 16px);
  margin-top: clamp(6px, 1.4vh, 16px);
  animation: surgir 1000ms cubic-bezier(0.22, 1, 0.36, 1) 760ms both;
}

.trilho {
  position: relative;
  width: clamp(190px, 38vw, 420px);
  z-index: 1;
  height: 2px;
  overflow: hidden;
  border-radius: 999px;
  /* O trilho apagado: visível o bastante para o olho saber o caminho,
     fraco o bastante para o núcleo ser a única coisa acesa. */
  background: linear-gradient(
    90deg,
    transparent,
    rgba(139, 92, 246, 0.22) 18%,
    rgba(167, 139, 250, 0.3) 50%,
    rgba(139, 92, 246, 0.22) 82%,
    transparent
  );
}

/*
  O núcleo e o rastro são a mesma coisa: uma faixa estreita com
  gradiente, em que a cauda é o próprio gradiente se apagando para trás.
  Desenhar rastro separado custaria mais uma camada pelo mesmo efeito.
*/
.nucleo {
  position: absolute;
  top: -1px;
  left: 0;
  width: 42%;
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(124, 58, 237, 0.35) 45%,
    rgba(196, 164, 255, 0.95) 88%,
    #ffffff 97%,
    rgba(255, 255, 255, 0) 100%
  );
  box-shadow: 0 0 14px rgba(167, 139, 250, 0.75);
  /* Sai devagar, cruza, chega devagar — e recomeça do outro lado sem
     dar marcha a ré. */
  animation: percorrer 3.4s cubic-bezier(0.55, 0, 0.3, 1) infinite;
}

@keyframes percorrer {
  0% {
    transform: translateX(-105%);
    opacity: 0;
  }
  12% {
    opacity: 1;
  }
  88% {
    opacity: 1;
  }
  100% {
    transform: translateX(242%);
    opacity: 0;
  }
}

/* Faíscas: três pontos parados no trilho que acendem quando o núcleo
   passa perto. Períodos diferentes do núcleo, para o conjunto nunca
   cair num compasso óbvio. */
.faisca {
  position: absolute;
  top: 50%;
  width: 3px;
  height: 3px;
  margin-top: -1.5px;
  border-radius: 50%;
  background: var(--roxo-claro);
  opacity: 0;
  animation: faiscar 3.4s ease-in-out infinite;
}

.f1 {
  left: 18%;
  animation-delay: 0.42s;
}
.f2 {
  left: 52%;
  animation-delay: 1.58s;
}
.f3 {
  left: 81%;
  animation-delay: 2.62s;
}

@keyframes faiscar {
  0%,
  70%,
  100% {
    opacity: 0;
    transform: scale(0.6);
  }
  8% {
    opacity: 0.9;
    transform: scale(1.4);
  }
  22% {
    opacity: 0;
    transform: scale(0.8);
  }
}

.rotulo {
  position: relative;
  z-index: 1;
  margin: 0;
  font-size: clamp(8.5px, 0.4vw + 7px, 10.5px);
  font-weight: 600;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
  color: rgba(183, 180, 199, 0.85);
}

/* ============================================ molduras de canto */

.cantos {
  position: fixed;
  inset: clamp(18px, 3vw, 44px);
  pointer-events: none;
  animation: aparecer 1400ms ease 700ms both;
}

.canto {
  position: absolute;
  width: clamp(26px, 4vw, 52px);
  height: clamp(26px, 4vw, 52px);
  border: 0 solid rgba(139, 92, 246, 0.32);
}

.ce {
  top: 0;
  left: 0;
  border-top-width: 1px;
  border-left-width: 1px;
}
.cd {
  top: 0;
  right: 0;
  border-top-width: 1px;
  border-right-width: 1px;
}
.be {
  bottom: 0;
  left: 0;
  border-bottom-width: 1px;
  border-left-width: 1px;
}
.bd {
  bottom: 0;
  right: 0;
  border-bottom-width: 1px;
  border-right-width: 1px;
}

@keyframes aparecer {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* =================================================== adaptações */

@media (max-width: 560px) {
  .cantos {
    display: none;
  }
}

/*
  Celular em pé é alto e estreito, e centrar a composição no espaço
  inteiro deixa um vão morto entre o cabeçalho e a marca. Um rodapé
  maior empurra o centro para cima: a marca sobe, e a cidade ocupa a
  faixa de baixo que antes ficava vazia.
*/
@media (max-width: 560px) and (min-height: 700px) {
  .palco {
    padding-bottom: 13vh;
  }
}

@media (max-width: 560px) {
  .recado {
    letter-spacing: 0.13em;
    text-indent: 0.13em;
    line-height: 1.75;
  }
  .rotulo {
    letter-spacing: 0.18em;
    text-indent: 0.18em;
  }
}

/* Telas bem estreitas: o título precisa caber sem partir palavra. */
@media (max-width: 400px) {
  .titulo {
    font-size: clamp(22px, 7.2vw, 30px);
    letter-spacing: 0.02em;
    text-indent: 0.02em;
  }
  .trilho {
    width: 78vw;
  }
}

/* Tela baixa e larga — celular deitado, notebook pequeno. Altura é o
   recurso escasso: a composição encolhe em vez de ser cortada. */
@media (max-height: 560px) and (orientation: landscape) {
  .palco {
    gap: 8px;
    padding-bottom: 16px;
  }
  .coruja {
    width: clamp(80px, 15vh, 124px);
  }
  .assinatura {
    width: clamp(128px, 25vh, 210px);
  }
  .titulo {
    font-size: clamp(21px, 5.2vh, 42px);
  }
  .energia {
    margin-top: 2px;
    gap: 6px;
  }
  .cantos {
    display: none;
  }
}

/*
  Movimento reduzido: a página chega pronta. Sem entrada, sem neon
  pulsando, sem núcleo percorrendo o trilho — que vira uma linha acesa
  e parada, ainda coerente com o resto.
*/
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
  .palco {
    translate: none;
  }
  .nucleo {
    transform: translateX(58%);
    opacity: 0.9;
  }
  .faisca {
    opacity: 0.55;
  }
}
