/*
 * Órbita cassiellOS — a camada visual da assinatura de inicialização.
 *
 * Reprodução web do asset do Brand Lab. Os números aqui NÃO são estéticos livres: diâmetros,
 * durações e sentidos vêm medidos do original e estão espelhados em `orbita.js` (`ORBITAS`).
 * Quem mudar um, muda os dois — e o teste compara os dois.
 *
 *   anel   diâmetro   proporção   duração   sentido    ponto
 *   R1     300 px     57,7 %      20 s      normal     Signal Red
 *   R2     410 px     78,8 %      27 s      reverse    System Blue
 *   R3     520 px     100 %       36 s      normal     Flow Cyan (tracejada)
 *
 * O asset foi criado em comp 800x800. Na web o diâmetro máximo é RESPONSIVO: travar 520px
 * cortaria a órbita externa em tela pequena, e é ela que dá a composição inteira.
 *
 * CUSTO
 * -----
 * Só `transform` e `opacity` animam. Nada anima `filter`, `box-shadow`, `width` ou `top` — é o
 * que mantém a coisa na GPU e fora do caminho de layout. O glow dos pontos existe, mas é
 * estático.
 */

/* ============================================================ diâmetro responsivo */

.cs-orb{
  /* O anel externo nunca encosta na borda: `vmin` garante que a composição inteira caiba em
     qualquer proporção de tela, retrato ou paisagem. */
  --cs-orb-d:min(560px,72vmin);
  --cs-orb-linha:rgba(255,255,255,.07);
  --cs-orb-linha-forte:rgba(255,255,255,.10);
  --cs-orb-flutuacao:calc(var(--cs-orb-d) * .0269);   /* 14px em 520px, proporcional */

  position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;
  width:100%;min-height:100%;
  font-family:var(--cassiellos-font-body,Inter,Arial,sans-serif);
}
.cs-orb--lg{--cs-orb-d:min(420px,62vmin)}
.cs-orb--md{--cs-orb-d:min(280px,48vmin)}
.cs-orb--sm{--cs-orb-d:min(168px,38vmin)}

/* variante embutida: sem tela cheia, para a operação realmente excepcional */
.cs-orb--inline{min-height:auto;padding:26px 0}

/* ============================================================ host de boot (tela cheia) */

.cs-orb-host{
  position:fixed;inset:0;z-index:9000;
  display:flex;align-items:center;justify-content:center;
  background:var(--cassiellos-navy,#07101F);
  opacity:1;
  transition:opacity .22s ease,transform .22s ease;
}
/* Transição de saída: opacidade + escala mínima. Sem cinematografia — 220ms. */
.cs-orb-saindo{opacity:0;transform:scale(1.012);pointer-events:none}

/* Enquanto a Órbita está no ar, o que está atrás dela não rola. */
body.cs-orb-bootando{overflow:hidden}

/* ============================================================ palco */

.cs-orb-palco{
  position:relative;display:grid;place-items:center;
  width:var(--cs-orb-d);height:var(--cs-orb-d);
}

/*
 * GRID TÉCNICO
 *
 * Textura de sistema, não papel quadriculado. Células grandes, opacidade muito baixa, e uma
 * máscara radial que dissolve as bordas — sem ela o quadrado do grid aparece e a composição
 * ganha um retângulo que não existe no asset.
 */
.cs-orb-grade{
  position:absolute;inset:-18%;
  background-image:
    linear-gradient(to right,rgba(255,255,255,.028) 1px,transparent 1px),
    linear-gradient(to bottom,rgba(255,255,255,.028) 1px,transparent 1px);
  background-size:clamp(44px,7vmin,72px) clamp(44px,7vmin,72px);
  -webkit-mask-image:radial-gradient(circle at 50% 50%,#000 32%,transparent 78%);
  mask-image:radial-gradient(circle at 50% 50%,#000 32%,transparent 78%);
  pointer-events:none;
}

.cs-orb-aneis{
  position:relative;
  width:var(--cs-orb-d);height:var(--cs-orb-d);
  display:grid;place-items:center;
}

/* ============================================================ anéis */

/*
 * `inset:0; margin:auto` com largura explícita centraliza sem `translate` — assim a animação
 * mexe SÓ em `rotate`, e o ponto viaja porque o anel inteiro gira. Nenhuma coordenada de ponto é
 * calculada por frame.
 */
.cs-orb-anel{
  position:absolute;inset:0;margin:auto;
  border-radius:50%;
  border:1px solid var(--cs-orb-linha);
  will-change:transform;
  animation-name:cs-orb-girar;
  animation-timing-function:linear;
  animation-iteration-count:infinite;
}
.cs-orb-anel--r1{width:57.7%;height:57.7%;animation-duration:20s;animation-direction:normal}
.cs-orb-anel--r2{width:78.8%;height:78.8%;animation-duration:27s;animation-direction:reverse}
.cs-orb-anel--r3{width:100%;height:100%;animation-duration:36s;animation-direction:normal}

/* R3 tracejada, muito sutil. `border-style:dashed` desenha o pontilhado sem imagem nem SVG. */
.cs-orb-anel--tracejada{border-style:dashed;border-color:var(--cs-orb-linha-forte)}

@keyframes cs-orb-girar{ from{transform:rotate(0deg)} to{transform:rotate(360deg)} }

/* ============================================================ pontos */

/*
 * Núcleo sólido + glow suave, e o glow é `box-shadow` ESTÁTICO. Animar sombra grande é o caminho
 * mais curto para um loader que come CPU numa máquina modesta — exatamente a máquina em que uma
 * tela de carregamento importa mais.
 */
.cs-orb-ponto{
  position:absolute;top:-4px;left:50%;
  width:8px;height:8px;margin-left:-4px;
  border-radius:50%;display:block;
}
.cs-orb-ponto--red{ background:var(--cassiellos-signal-red,#F13C4B); box-shadow:0 0 12px 1px rgba(241,60,75,.55)}
.cs-orb-ponto--blue{background:var(--cassiellos-system-blue,#246BFF);box-shadow:0 0 12px 1px rgba(36,107,255,.5)}
.cs-orb-ponto--cyan{background:var(--cassiellos-flow-cyan,#22C7F2); box-shadow:0 0 12px 1px rgba(34,199,242,.45)}

/* ============================================================ símbolo */

/*
 * O símbolo oficial, branco, ao centro. A sombra vermelha do Brand Lab aparece — em dose muito
 * baixa. Ela é assinatura, não glow: se for percebida como brilho, está exagerada.
 */
.cs-orb-simbolo{
  position:relative;z-index:2;
  width:26%;height:auto;
  filter:drop-shadow(0 0 18px rgba(241,60,75,.16));
  animation:cs-orb-flutuar 5s ease-in-out infinite;
  will-change:transform;
}
@keyframes cs-orb-flutuar{
  0%,100%{transform:translateY(calc(var(--cs-orb-flutuacao) * -.5))}
  50%    {transform:translateY(calc(var(--cs-orb-flutuacao) * .5))}
}

/* ============================================================ mensagem */

.cs-orb-mensagem{margin-top:clamp(20px,4vmin,38px);text-align:center;padding:0 22px;max-width:min(440px,86vw)}
.cs-orb-titulo{
  margin:0;font-family:var(--cassiellos-font-display,'Inter Tight',Inter,Arial,sans-serif);
  font-size:clamp(15px,2.1vmin,18px);font-weight:600;letter-spacing:-.2px;
  color:var(--cassiellos-paper,#F6F8FF);
}
.cs-orb-sub{
  margin:7px 0 0;font-size:clamp(11px,1.5vmin,12.5px);line-height:1.5;
  color:var(--cassiellos-gray,#A8B4C9);
}

/* ============================================================ falha de boot */

/*
 * A Órbita NÃO continua girando quando o boot falha: o palco inteiro é substituído. Se ela
 * seguisse rodando, a tela estaria afirmando "ainda estou trabalhando" sobre um trabalho que
 * já acabou — e acabou mal.
 */
.cs-orb--falha{justify-content:center}
.cs-orb-falha-cartao{
  max-width:min(460px,88vw);padding:34px 30px;text-align:center;
  border:1px solid rgba(241,60,75,.28);border-radius:var(--cassiellos-radius-md,16px);
  background:rgba(241,60,75,.05);
}
.cs-orb-falha-marca{width:78px;height:auto;opacity:.72;margin-bottom:16px}
.cs-orb-falha-cartao h1{
  margin:0 0 10px;font-size:19px;letter-spacing:-.3px;
  font-family:var(--cassiellos-font-display,'Inter Tight',Inter,Arial,sans-serif);
  color:var(--cassiellos-paper,#F6F8FF);
}
.cs-orb-falha-cartao p{margin:0 0 8px;font-size:13px;line-height:1.55;color:var(--cassiellos-gray,#A8B4C9)}
.cs-orb-protocolo{font-size:12px}
.cs-orb-protocolo code{
  padding:2px 7px;border-radius:6px;font-size:12px;
  background:rgba(255,255,255,.06);color:var(--cassiellos-mist,#DCE3EE);
}
.cs-orb-falha-cartao button{width:auto;margin-top:16px;padding:11px 22px}

/* ============================================================ reduced motion */

/*
 * A composição PERMANECE: símbolo, três órbitas, três pontos e a mensagem continuam na tela.
 * O que sai é o movimento.
 *
 * Sem os ângulos fixos abaixo, os três pontos parariam todos às 12 horas — a composição
 * viraria uma coluna de pontos alinhados, que não é o desenho do Brand Lab. Os ângulos são os
 * mesmos declarados em `orbita.js` (`ORBITAS[].angulo`).
 */
@media (prefers-reduced-motion:reduce){
  .cs-orb-anel,.cs-orb-simbolo{animation:none!important}
  .cs-orb-anel--r1{transform:rotate(0deg)}
  .cs-orb-anel--r2{transform:rotate(140deg)}
  .cs-orb-anel--r3{transform:rotate(260deg)}
  .cs-orb-simbolo{transform:none}
  .cs-orb-host{transition:none}
}
/* O mesmo, quando o modo reduzido é FORÇADO pelo parâmetro `reducedMotion` e não pelo sistema. */
.cs-orb[data-movimento="reduzido"] .cs-orb-anel,
.cs-orb[data-movimento="reduzido"] .cs-orb-simbolo{animation:none!important}
.cs-orb[data-movimento="reduzido"] .cs-orb-anel--r1{transform:rotate(0deg)}
.cs-orb[data-movimento="reduzido"] .cs-orb-anel--r2{transform:rotate(140deg)}
.cs-orb[data-movimento="reduzido"] .cs-orb-anel--r3{transform:rotate(260deg)}
.cs-orb[data-movimento="reduzido"] .cs-orb-simbolo{transform:none}

/* ============================================================ responsividade */

/*
 * Nada de dimensão fixa: o diâmetro é `vmin`, então a órbita externa nunca é cortada. Em telas
 * baixas a mensagem encolhe antes da composição, porque é a composição que carrega a identidade.
 */
@media (max-width:680px){
  .cs-orb{--cs-orb-d:min(360px,74vmin)}
  .cs-orb-mensagem{margin-top:26px}
  .cs-orb-falha-cartao{padding:26px 20px}
}
@media (max-height:520px){
  .cs-orb{--cs-orb-d:min(260px,58vmin)}
  .cs-orb-mensagem{margin-top:16px}
}
