/* Two cached monochrome textures, shifted without opacity flicker. */
.noise {
  position: fixed;
  z-index: 20;
  inset: 0;
  overflow: hidden;
  contain: strict;
  pointer-events: none;
  opacity: 1;
  background: none;
  transform: none;
  animation: none;
}

.noise::before,
.noise::after {
  content: "";
  position: absolute;
  inset: -18px;
  pointer-events: none;
  background-repeat: repeat;
  will-change: transform;
}

/* The opening frame carries a slightly stronger, larger 16 mm texture. */
.hero::after {
  content: "";
  position: absolute;
  z-index: 0;
  inset: -18px;
  pointer-events: none;
  background: url("assets/grain-coarse.svg") repeat;
  background-size: 220px 220px;
  opacity: .055;
  animation: grain-coarse-shift 2.1s steps(1, end) infinite;
}

.noise::before {
  background-image: url("assets/grain-fine.svg");
  background-size: 192px 192px;
  opacity: .075;
  animation: grain-fine-shift 1.2s steps(1, end) infinite;
}

.noise::after {
  background-image: url("assets/grain-coarse.svg");
  background-size: 288px 288px;
  opacity: .023;
  animation: grain-coarse-shift 1.8s steps(1, end) infinite;
}

@keyframes grain-fine-shift {
  0%, 100% { transform: translate3d(0, 0, 0); }
  16% { transform: translate3d(-11px, 7px, 0); }
  33% { transform: translate3d(8px, -13px, 0); }
  50% { transform: translate3d(-6px, -3px, 0); }
  66% { transform: translate3d(13px, 10px, 0); }
  83% { transform: translate3d(-14px, -9px, 0); }
}

@keyframes grain-coarse-shift {
  0%, 100% { transform: translate3d(6px, -4px, 0); }
  25% { transform: translate3d(-8px, 13px, 0); }
  50% { transform: translate3d(11px, 6px, 0); }
  75% { transform: translate3d(-13px, -10px, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .noise::before,
  .noise::after,
  .hero::after {
    animation: none;
    transform: none;
    will-change: auto;
  }
}
