/* Secfense Ghost - page background + "magic halo" around a box.
   Extracted from the Ghost console sign-in screen. Pure CSS, no JS.

   Two pieces, independent of each other:
     1. the page background (.halo-page + .halo-vignette)
     2. the effect wrapper (.magic-halo) - wraps ANY box.

   Everything tunable sits in the :root variables below. */

/* ------------------------------------------------------------------ tokens */
:root {
  --halo-bg: #0e0f25;            /* page background */

  /* Ring stops (the 1px border around the box). Order matters: the last stop
     meets the first when the gradient spins. */
  --halo-ring-1: #a3a5f3;        /* light violet */
  --halo-ring-2: #7171ff;        /* violet, at 40% */
  --halo-ring-3: #4a4ac6;        /* deep violet, at 70% */
  --halo-ring-4: #44d7ea;        /* cyan */

  /* Glow stops (the blurred halo underneath). Deliberately darker mids than
     the ring so the halo reads as light bleeding out, not as a copy. */
  --halo-glow-1: #7171ff;
  --halo-glow-2: #4a4ac6;        /* at 45% */
  --halo-glow-3: #42407d;        /* at 75% */
  --halo-glow-4: #44d7ea;

  --halo-ring-width: 1px;        /* the visible border thickness */
  --halo-speed: 8s;              /* one full rotation */
  --halo-blur: 70px;
  --halo-opacity: 0.45;
  /* How far the glow spills past the box. Slight downward bias (top smaller
     than bottom via inset shorthand + top override) makes it sit "under"
     the box like a light source behind it. */
}

/* ------------------------------------------------------- page background */
.halo-page {
  min-height: 100vh;
  position: relative;
  display: grid;
  place-items: center;
  padding: 48px 24px;
  box-sizing: border-box;
  background: var(--halo-bg);
  /* The blurred halo spills far past the box; clip it at the page edge so
     no scrollbars appear. */
  overflow: hidden;
}

/* Soft violet pool of light behind the box - a separate layer, so it stays
   put while the halo animates. */
.halo-vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(60% 55% at 50% 45%, rgba(113, 113, 255, 0.10), transparent 70%);
}

/* --------------------------------------------------------------- the halo */
/* A registered custom property is what lets the ANGLE of a linear-gradient
   animate - a plain custom property cannot interpolate. One spinning
   gradient, used twice: as the ring (the wrapper's padding is the ring) and
   as the same gradient blurred into the glow underneath.
   Where @property is unsupported (Firefox < 128) the angle cannot animate
   and the effect degrades to a static ring and glow - not to nothing. */
@property --halo-rotate {
  syntax: "<angle>";
  initial-value: 132deg;
  inherits: false;
}

.magic-halo {
  position: relative;
  /* Creates a stacking context so the glow's z-index: -1 lands just behind
     THIS element. Without it the glow sinks beneath the page's opaque
     background and is simply invisible. Do not remove. */
  z-index: 0;
  padding: var(--halo-ring-width);
  background: linear-gradient(
    var(--halo-rotate),
    var(--halo-ring-1),
    var(--halo-ring-2) 40%,
    var(--halo-ring-3) 70%,
    var(--halo-ring-4)
  );
  animation: halo-spin var(--halo-speed) linear infinite;
}

/* The box inside must cover the wrapper's gradient completely - opaque
   background, no border, and it must sit above the gradient. */
.magic-halo > * {
  position: relative;
  z-index: 1;
  border: 0;
}

.magic-halo::after {
  content: "";
  position: absolute;
  inset: -8% -10%;   /* bigger than the box on every side */
  top: -4%;          /* ...but less on top: the glow hangs low */
  z-index: -1;
  background: linear-gradient(
    var(--halo-rotate),
    var(--halo-glow-1),
    var(--halo-glow-2) 45%,
    var(--halo-glow-3) 75%,
    var(--halo-glow-4)
  );
  filter: blur(var(--halo-blur));
  opacity: var(--halo-opacity);
  animation: halo-spin var(--halo-speed) linear infinite;
}

@keyframes halo-spin {
  0% { --halo-rotate: 0deg; }
  100% { --halo-rotate: 360deg; }
}

@media (prefers-reduced-motion: reduce) {
  .magic-halo,
  .magic-halo::after { animation: none; }
}
