@property --blob1-x { syntax: "<percentage>"; inherits: false; initial-value: 10%; }
@property --blob1-y { syntax: "<percentage>"; inherits: false; initial-value: 35%; }
@property --blob2-x { syntax: "<percentage>"; inherits: false; initial-value: 85%; }
@property --blob2-y { syntax: "<percentage>"; inherits: false; initial-value: 15%; }
@property --blob3-x { syntax: "<percentage>"; inherits: false; initial-value: 60%; }
@property --blob3-y { syntax: "<percentage>"; inherits: false; initial-value: 85%; }
@property --blob4-x { syntax: "<percentage>"; inherits: false; initial-value: 40%; }
@property --blob4-y { syntax: "<percentage>"; inherits: false; initial-value: 10%; }

@keyframes blob1-x { to { --blob1-x: 70%; } }
@keyframes blob1-y { to { --blob1-y: 60%; } }
@keyframes blob2-x { to { --blob2-x: 20%; } }
@keyframes blob2-y { to { --blob2-y: 80%; } }
@keyframes blob3-x { to { --blob3-x: 55%; } }
@keyframes blob3-y { to { --blob3-y: 20%; } }
@keyframes blob4-x { to { --blob4-x: 80%; } }
@keyframes blob4-y { to { --blob4-y: 65%; } }

.grainy {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}

.grainy::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(
      ellipse 38% 55% at var(--blob1-x) var(--blob1-y),
      rgba(255, 110, 20, 0.65),
      transparent 68%
    ),
    radial-gradient(
      ellipse 55% 32% at var(--blob2-x) var(--blob2-y),
      rgba(210, 25, 45, 0.6),
      transparent 65%
    ),
    radial-gradient(
      ellipse 42% 60% at var(--blob3-x) var(--blob3-y),
      rgba(20, 160, 90, 0.55),
      transparent 70%
    ),
    radial-gradient(
      ellipse 60% 38% at var(--blob4-x) var(--blob4-y),
      rgba(90, 40, 220, 0.55),
      transparent 68%
    );
  filter: blur(70px);
  animation:
    blob1-x 20s ease-in-out infinite alternate,
    blob1-y 27s ease-in-out infinite alternate,
    blob2-x 32s ease-in-out infinite alternate,
    blob2-y 18s ease-in-out infinite alternate,
    blob3-x 24s ease-in-out infinite alternate,
    blob3-y 36s ease-in-out infinite alternate,
    blob4-x 28s ease-in-out infinite alternate,
    blob4-y 22s ease-in-out infinite alternate;
  pointer-events: none;
  z-index: -2;
}

.grainy::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
  background-repeat: repeat;
  mix-blend-mode: screen;
  opacity: 0.5;
  pointer-events: none;
  z-index: -1;
}
