/*
  Microgen CRT — character-generator broadcast look for the Quanta Microgen
  recreation font. Every artifact is a CSS custom property so amounts can be
  tuned live (and later mapped 1:1 to DaVinci Resolve OFX plugin params).
*/

@font-face {
  font-family: 'Quanta Microgen';
  src: url('QuantaMicrogen.woff2') format('woff2'),
       url('QuantaMicrogen.otf') format('opentype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Quanta Microgen';
  src: url('QuantaMicrogenBold.woff2') format('woff2'),
       url('QuantaMicrogenBold.otf') format('opentype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

.mg-crt {
  --mg-color: #ff3527;
  --mg-bg: transparent;

  /* bloom: electron-beam overdrive spreading past the glyph edge */
  --mg-bloom-blur: 0.5px;
  --mg-bloom-opacity: 0.35;

  /* the black keyline character generators matted behind text for legibility */
  --mg-outline-width: 1.5px;

  /* chromatic aberration: composite/RF color-channel misregistration */
  --mg-aberration-offset: 1.25px;
  --mg-aberration-opacity: 0.05;

  /* softening from video bandwidth limits */
  --mg-blur: 1.6px;

  /* scanlines */
  --mg-scan-opacity: 0;
  --mg-scan-size: 1px;

  /* vignette / tube curvature darkening at the edges */
  --mg-vignette-opacity: 0;

  /* interlace roll flicker */
  --mg-flicker-amount: 0.02;

  /* vertical jitter, sub-pixel */
  --mg-jitter-amount: 1.8px;

  /* dot-crawl style noise overlay */
  --mg-noise-opacity: 0.35;

  /* font weight: 400 (regular) or 700 (bold), matches the two @font-face weights above */
  --mg-weight: 700;

  /* VHS distress -------------------------------------------------------- */

  /* chroma bleed: color smearing sideways off the luma edge */
  --mg-bleed-amount: 0.3;

  /* tracking error: momentary line-tear / horizontal glitch bursts */
  --mg-tracking-amount: 0;

  /* head-switching noise band at the bottom of frame */
  --mg-headswitch-amount: 0;

  /* tape dropout: random white/black streak flicks */
  --mg-dropout-amount: 0;

  /* color instability: hue/saturation drift from unstable chroma lock */
  --mg-colordrift-amount: 0.65;

  /* ghost/trail: signal ringing behind the trailing edge */
  --mg-ghost-amount: 0.4;

  /* generation loss: composite contrast/saturation/blur degradation from re-dubbing */
  --mg-genloss-amount: 0;

  position: relative;
  overflow: hidden;
  background: var(--mg-bg);
  isolation: isolate;
  filter:
    contrast(calc(1 - var(--mg-genloss-amount) * 0.25))
    saturate(calc(1 - var(--mg-genloss-amount) * 0.45))
    blur(calc(var(--mg-genloss-amount) * 0.5px));
}

/* text ---------------------------------------------------------------- */

.mg-text {
  position: relative;
  display: block;
  width: 100%;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  font-family: 'Quanta Microgen', monospace;
  font-weight: var(--mg-weight);
  color: var(--mg-color);
  animation: mg-jitter 0.15s steps(2, jump-none) infinite,
             mg-flicker 4s linear infinite,
             mg-tracking-clip 2.5s steps(1) infinite,
             mg-colordrift 6s ease-in-out infinite;
  text-shadow:
    0 0 calc(var(--mg-bloom-blur) * 0.5) rgba(255, 255, 255, var(--mg-bloom-opacity)),
    0 0 var(--mg-bloom-blur) rgba(255, 255, 255, calc(var(--mg-bloom-opacity) * 0.6)),
    0 0 calc(var(--mg-bloom-blur) * 2.2) rgba(255, 255, 255, calc(var(--mg-bloom-opacity) * 0.3)),
    0 var(--mg-outline-width) 0 #000,
    0 calc(-1 * var(--mg-outline-width)) 0 #000,
    var(--mg-outline-width) 0 0 #000,
    calc(-1 * var(--mg-outline-width)) 0 0 #000,
    calc(var(--mg-bleed-amount) * 8px) 0 calc(var(--mg-bleed-amount) * 6px) rgba(255, 0, 60, calc(var(--mg-bleed-amount) * 0.6)),
    calc(var(--mg-bleed-amount) * -8px) 0 calc(var(--mg-bleed-amount) * 6px) rgba(0, 200, 255, calc(var(--mg-bleed-amount) * 0.6)),
    calc(var(--mg-ghost-amount) * -14px) calc(var(--mg-ghost-amount) * 2px) calc(var(--mg-ghost-amount) * 3px) rgba(255, 255, 255, calc(var(--mg-ghost-amount) * 0.35));
}

.mg-align-left { text-align: left; }
.mg-align-center { text-align: center; }
.mg-align-right { text-align: right; }

/* chromatic aberration ghosts, driven off a data-text mirror of the content */
.mg-text::before,
.mg-text::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  mix-blend-mode: screen;
  pointer-events: none;
}

.mg-text::before {
  color: #ff2a2a;
  transform: translateX(calc(-1 * var(--mg-aberration-offset)));
  opacity: var(--mg-aberration-opacity);
}

.mg-text::after {
  color: #2ad4ff;
  transform: translateX(var(--mg-aberration-offset));
  opacity: var(--mg-aberration-opacity);
}

/* screen overlays ------------------------------------------------------- */

.mg-crt::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, var(--mg-scan-opacity)) 0px,
    rgba(0, 0, 0, var(--mg-scan-opacity)) 1px,
    transparent 1px,
    transparent var(--mg-scan-size)
  );
  mix-blend-mode: multiply;
}

.mg-crt::after {
  content: '';
  position: absolute;
  inset: -10%;
  z-index: 3;
  pointer-events: none;
  background: radial-gradient(
    ellipse at center,
    transparent 55%,
    rgba(0, 0, 0, var(--mg-vignette-opacity)) 100%
  );
}

.mg-noise {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  opacity: var(--mg-noise-opacity);
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  animation: mg-noise-shift 0.4s steps(4) infinite;
}

/* head-switching noise band — the roll of static at the bottom of a VHS frame */
.mg-headswitch {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(3% + var(--mg-headswitch-amount) * 5%);
  z-index: 5;
  pointer-events: none;
  opacity: var(--mg-headswitch-amount);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 120px 40px;
  filter: contrast(1.8) brightness(1.4);
  mix-blend-mode: screen;
  animation: mg-headswitch-roll 0.5s steps(3) infinite;
}

/* tape dropout — brief white/black streak flicks from lost oxide/signal */
.mg-dropout {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  mix-blend-mode: screen;
  background:
    repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.85) 0px, rgba(255, 255, 255, 0.85) 1px, transparent 1px, transparent 40px),
    repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.6) 0px, rgba(255, 255, 255, 0.6) 1px, transparent 1px, transparent 77px);
  animation: mg-dropout-flicker 2s steps(1) infinite;
}

/* keyframes ------------------------------------------------------------- */

@keyframes mg-jitter {
  0%, 100% { transform: translate(0, 0); }
  8%  { transform: translate(0, var(--mg-jitter-amount)); }
  50% { transform: translate(0, var(--mg-jitter-amount)); }
  95% { transform: translate(calc(var(--mg-tracking-amount) * 14px), var(--mg-jitter-amount)); }
  96% { transform: translate(calc(var(--mg-tracking-amount) * -10px), 0); }
  97% { transform: translate(calc(var(--mg-tracking-amount) * 8px), var(--mg-jitter-amount)); }
  98% { transform: translate(0, 0); }
}

@keyframes mg-flicker {
  0%, 100% { opacity: 1; }
  55% { opacity: calc(1 - var(--mg-flicker-amount) * 0.5); }
  92% { opacity: 1; }
  93% { opacity: calc(1 - var(--mg-flicker-amount)); }
  94% { opacity: 1; }
}

/* clip-path bands synced to the tracking bursts in mg-jitter — line-tear look.
   Scaled by --mg-tracking-amount so it collapses to a no-op inset(0 0 0 0)
   at amount 0 instead of always clipping the text on the same cycle. */
@keyframes mg-tracking-clip {
  0%, 94%, 98%, 100% { clip-path: inset(0 0 0 0); }
  95% { clip-path: inset(calc(var(--mg-tracking-amount) * 20%) 0 calc(var(--mg-tracking-amount) * 55%) 0); }
  96% { clip-path: inset(calc(var(--mg-tracking-amount) * 60%) 0 calc(var(--mg-tracking-amount) * 5%) 0); }
  97% { clip-path: inset(0 0 calc(var(--mg-tracking-amount) * 80%) 0); }
}

@keyframes mg-colordrift {
  0%, 100% { filter: blur(var(--mg-blur)) saturate(1) hue-rotate(0deg); }
  50% {
    filter: blur(var(--mg-blur))
      saturate(calc(1 + var(--mg-colordrift-amount) * 0.6))
      hue-rotate(calc(var(--mg-colordrift-amount) * 20deg));
  }
}

@keyframes mg-noise-shift {
  0%   { background-position: 0 0; }
  25%  { background-position: -20px 10px; }
  50%  { background-position: 15px -15px; }
  75%  { background-position: -10px -10px; }
  100% { background-position: 0 0; }
}

@keyframes mg-headswitch-roll {
  0%   { background-position: 0 0; transform: translateY(0); }
  50%  { background-position: -40px 20px; transform: translateY(-2px); }
  100% { background-position: 0 0; transform: translateY(0); }
}

@keyframes mg-dropout-flicker {
  0%, 80% { opacity: 0; }
  81% { opacity: calc(var(--mg-dropout-amount) * 1); background-position-y: 12px, 5px; }
  83% { opacity: 0; }
  84% { opacity: calc(var(--mg-dropout-amount) * 0.7); background-position-y: 55px, 30px; }
  86%, 100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .mg-text,
  .mg-noise,
  .mg-headswitch,
  .mg-dropout {
    animation: none;
  }
}
