/*
  crt.css: animated CRT effect for the homepage.
  Load it AFTER style.css.

  Quick dials (0 turns a layer off):
*/
:root {
  --crt-halo: 1;      /* the radial halo around the angels   */
  --crt-bands: 0.85;  /* strength of the blue/yellow bands   */
  --crt-scan: 0.28;   /* how dark the scanlines are          */
  --crt-noise: 0.22;  /* strength of the static              */
}

/* ------------------------------------------------------------------
   No frame: the page runs edge to edge
------------------------------------------------------------------- */
body {
  padding: 0;
  gap: 0;
}

.frame {
  background: transparent;
  box-shadow: none;
}

/* keep the little "homepage" label, but float it so it doesn't push the page down */
.page-label {
  position: fixed;
  top: 0.8rem;
  left: 1rem;
  z-index: 2;
}

/* ------------------------------------------------------------------
   Radial halo: a bright core with rings of cyan, blue, violet and
   orange that ripple outward from the angels and fade out before the
   edges (so the corners stay green).
   Needs the empty <div class="crt-halo"> before the bands div.
------------------------------------------------------------------- */
@property --halo-shift {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}

.crt-halo {
  --halo-shift: 0%;
  position: fixed;
  inset: 0;
  pointer-events: none;
  opacity: var(--crt-halo);

  background:
    /* hot white core right behind the angels */
    radial-gradient(
      ellipse 20% 28% at 50% 48%,
      rgba(255, 255, 255, .95) 0%,
      rgba(210, 245, 255, .6) 55%,
      rgba(210, 245, 255, 0) 100%
    ),
    /* the rippling rings */
    repeating-radial-gradient(
      ellipse 72% 88% at 50% 48%,
      rgba(235, 255, 255, 1)  calc(0%  + var(--halo-shift)),
      rgba(110, 215, 255, 1)  calc(5%  + var(--halo-shift)),
      rgba(40, 100, 255, 1)   calc(11% + var(--halo-shift)),
      rgba(120, 60, 230, .8)  calc(17% + var(--halo-shift)),
      rgba(255, 150, 80, .65) calc(21% + var(--halo-shift)),
      rgba(235, 255, 255, 1)  calc(25% + var(--halo-shift))
    );

  /* fade the whole thing out toward the edges */
  -webkit-mask-image: radial-gradient(ellipse 58% 76% at 50% 48%, #000 25%, rgba(0, 0, 0, 0) 100%);
  mask-image: radial-gradient(ellipse 58% 76% at 50% 48%, #000 25%, rgba(0, 0, 0, 0) 100%);

  animation:
    halo-ripple 7s linear infinite,
    halo-pulse 3.2s ease-in-out infinite;
}

@keyframes halo-ripple {
  from { --halo-shift: 0%; }
  to   { --halo-shift: 25%; }
}

@keyframes halo-pulse {
  0%, 100% { filter: brightness(0.9); }
  50%      { filter: brightness(1.2); }
}

/* ------------------------------------------------------------------
   Colour bands: rolling blue / cyan / white / yellow interference.
   Behind the angel, so the ink lines stay dark on top.
------------------------------------------------------------------- */
.crt-bands {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: 200vh;
  pointer-events: none;
  opacity: var(--crt-bands);
  mix-blend-mode: screen;

  background-image: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0)         0%,
    rgba(40, 100, 255, 1)    9%,
    rgba(70, 210, 255, 1)    19%,
    rgba(255, 255, 255, 1)   26%,
    rgba(80, 170, 255, 1)    34%,
    rgba(0, 0, 0, 0)         46%,
    rgba(255, 235, 100, 1)   58%,
    rgba(255, 170, 70, .8)   68%,
    rgba(0, 0, 0, 0)         79%,
    rgba(60, 130, 255, .9)   89%,
    rgba(0, 0, 0, 0)         100%
  );
  background-size: 100% 100vh;
  background-repeat: repeat-y;

  /* a bit softer toward the left and right edges, but never fully gone */
  -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,.25) 0, #000 28%, #000 72%, rgba(0,0,0,.25) 100%);
  mask-image: linear-gradient(90deg, rgba(0,0,0,.25) 0, #000 28%, #000 72%, rgba(0,0,0,.25) 100%);

  animation:
    bands-drift 18s linear infinite,
    bands-pulse 2.4s ease-in-out infinite;
}

@keyframes bands-drift {
  from { transform: translateY(0); }
  to   { transform: translateY(-100vh); }
}

@keyframes bands-pulse {
  0%, 100% { filter: brightness(0.95); }
  50%      { filter: brightness(1.4); }
}

/* ------------------------------------------------------------------
   Top overlay: scanlines, static, roll bar, vignette.
   Never catches clicks.
------------------------------------------------------------------- */
.crt {
  position: fixed;
  inset: 0;
  z-index: 50;
  overflow: hidden;
  pointer-events: none;
  animation: crt-flicker 5s steps(1) infinite;
}

.crt > * {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.crt-scan {
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, var(--crt-scan)) 0,
    rgba(0, 0, 0, var(--crt-scan)) 2px,
    transparent 2px,
    transparent 4px
  );
  animation: scan-crawl 0.8s linear infinite;
}

@keyframes scan-crawl {
  from { background-position: 0 0; }
  to   { background-position: 0 4px; }
}

.crt-noise {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 220px 220px;
  opacity: var(--crt-noise);
  mix-blend-mode: overlay;
  animation: noise 0.5s steps(1, end) infinite;
}

@keyframes noise {
  0%   { background-position: 0 0; }
  20%  { background-position: -60px 40px; }
  40%  { background-position: 30px -80px; }
  60%  { background-position: -90px -20px; }
  80%  { background-position: 70px 90px; }
  100% { background-position: 0 0; }
}

/* the soft bright bar that rolls down the screen */
.crt-roll {
  inset: auto;
  left: 0;
  right: 0;
  top: 0;
  height: 22vh;
  background: linear-gradient(
    to bottom,
    transparent,
    rgba(255, 255, 255, .06) 40%,
    rgba(255, 255, 255, .16) 55%,
    rgba(255, 255, 255, .06) 70%,
    transparent
  );
  mix-blend-mode: screen;
  animation: roll 7s linear infinite;
}

@keyframes roll {
  from { transform: translateY(-100%); }
  to   { transform: translateY(500%); }
}

/* light vignette, tinted green instead of black so it doesn't dull the colours */
.crt-vignette {
  background: radial-gradient(ellipse at center, transparent 60%, rgba(10, 30, 10, .3) 100%);
}

@keyframes crt-flicker {
  0%, 100% { opacity: 1; }
  4%  { opacity: .9; }
  6%  { opacity: 1; }
  52% { opacity: .94; }
  53% { opacity: 1; }
  80% { opacity: .88; }
  81% { opacity: 1; }
}

/* ------------------------------------------------------------------
   Content: the angel gets colour fringing + jitter, and the text is
   pulled forward ABOVE the whole CRT layer (z-index 60 > 50).
------------------------------------------------------------------- */
.angel {
  filter:
    blur(3.5px)
    drop-shadow(-3px 0 rgba(0, 210, 255, .55))
    drop-shadow(3px 0 rgba(255, 40, 80, .45));
  animation: jitter 5s steps(1) infinite;
}

.title {
  z-index: 60;
  text-shadow:
    -2px 0 rgba(0, 255, 255, .55),
    2px 0 rgba(255, 40, 40, .5),
    0 0 18px rgba(229, 21, 146, .8);
  animation: jitter 5s steps(1) -2s infinite;
}

.links {
  z-index: 60;
  animation: jitter 5s steps(1) -3.5s infinite;
}

.links a {
  text-shadow:
    -1px 0 rgba(0, 255, 255, .5),
    1px 0 rgba(255, 40, 40, .45),
    0 0 10px rgba(229, 21, 146, .6);
}

@keyframes jitter {
  0%, 100% { translate: 0 0; }
  7%  { translate: 1px 0; }
  8%  { translate: -1px 0; }
  9%  { translate: 0 0; }
  47% { translate: 2px 0; }
  48% { translate: 0 0; }
  73% { translate: -2px 1px; }
  74% { translate: 0 0; }
}

/* a second copy of the angel, shown only in brief horizontal "tracking tear" slices */
.angel-glitch {
  filter:
    blur(2px)
    drop-shadow(-6px 0 rgba(255, 0, 80, .9))
    drop-shadow(6px 0 rgba(0, 230, 255, .9));
  animation: tear 6s steps(1) infinite;
}

@keyframes tear {
  0%, 62%, 66%, 87%, 100% { clip-path: inset(50% 0 50% 0); translate: 0 0; opacity: 0; }
  63% { clip-path: inset(22% 0 66% 0); translate: 18px 0;  opacity: 1; }
  64% { clip-path: inset(58% 0 30% 0); translate: -14px 0; opacity: 1; }
  65% { clip-path: inset(40% 0 52% 0); translate: 10px 0;  opacity: 1; }
  88% { clip-path: inset(70% 0 20% 0); translate: -20px 0; opacity: 1; }
  89% { clip-path: inset(12% 0 80% 0); translate: 12px 0;  opacity: 1; }
  90% { clip-path: inset(50% 0 50% 0); translate: 0 0;     opacity: 0; }
}

/* ------------------------------------------------------------------
   CRT "power on" when the page loads (delete this block if you'd
   rather it just appear)
------------------------------------------------------------------- */
.frame {
  animation: power-on 0.9s ease-out;
}

@keyframes power-on {
  0%   { transform: scale(0, 0.004); filter: brightness(8); }
  30%  { transform: scale(1, 0.004); filter: brightness(8); }
  60%  { transform: scale(1, 1.04);  filter: brightness(3); }
  100% { transform: scale(1, 1);     filter: brightness(1); }
}

/* ------------------------------------------------------------------
   Slightly lighter on phones, and off for anyone who asks for less motion
------------------------------------------------------------------- */
@media (max-width: 768px) {
  :root {
    --crt-noise: 0.15;
    --crt-bands: 0.7;
  }
}

@media (prefers-reduced-motion: reduce) {
  .crt-halo,
  .crt-bands,
  .crt,
  .crt-scan,
  .crt-noise,
  .crt-roll,
  .angel,
  .title,
  .links,
  .frame {
    animation: none;
  }

  .angel-glitch {
    display: none;
  }
}
