# Whack a mole 404

> A lawn with six burrows where a mole holding a 404 sign pops up; tap it in time to score a point.

- Category: [404](https://library.aimran.es/components/404)
- Built with: HTML + CSS
- Live editor: https://library.aimran.es/blocks/404-moles
- Library: AIMRAN Library (https://library.aimran.es), free, no sign-up, by Aimran Oukham

## Where to use it

A garden error page with a tiny game: six burrows in a bright green lawn, and a mole carrying a wooden 404 sign pops out of a random one for about a second. Catch it with a click, a tap or the keyboard and it squashes down while the counter goes up.

Each burrow is a real button with its own label and focus ring, so the game works without a mouse. The speed control changes how fast the mole appears. Adjust the sunflower accent and point the button home.

## Code

### HTML

```html
<!doctype html>
<html lang="es">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="robots" content="noindex" />
    <title>404 · Page not found</title>
    <style>
      body { margin: 0; background: #000; }
      .n4-moles {
        --accent: #f4c430;
        --k: 1;
        position: fixed;
        inset: 0;
        z-index: 0;
        overflow: hidden;
        container-type: size;
        display: grid;
        place-items: center;
        background: #000;
        color: #f5f5f7;
        font-family: -apple-system,BlinkMacSystemFont,"SF Pro Display","Inter","Segoe UI",system-ui,sans-serif;
        -webkit-font-smoothing: antialiased;
        text-align: center;
        line-height: 1.4;
      }
      
      .n4-moles *,.n4-moles *::before,.n4-moles *::after {
        box-sizing: border-box;
      }
      
      .n4-moles .n4-copy {
        position: relative;
        z-index: 5;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 1.6cqmin;
        width: 100%;
        max-width: 680px;
        padding: 0 6cqw;
      }
      
      .n4-moles .n4-title {
        margin: 0;
        font-size: clamp(17px,4.2cqmin,36px);
        font-weight: 600;
        letter-spacing: -.02em;
        line-height: 1.15;
        text-wrap: balance;
      }
      
      .n4-moles .n4-sub {
        margin: 0;
        max-width: 34em;
        font-size: clamp(13px,2.4cqmin,18px);
        color: #a1a1a6;
        text-wrap: balance;
      }
      
      .n4-moles .n4-tag {
        font: 600 clamp(10px,1.9cqmin,13px)/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
        letter-spacing: .16em;
        text-transform: uppercase;
        color: var(--accent);
      }
      
      .n4-moles .n4-cta {
        margin-top: 1.8cqmin;
        display: inline-flex;
        align-items: center;
        gap: .5em;
        padding: .85em 1.5em;
        border-radius: 999px;
        background: #f5f5f7;
        color: #000;
        font-size: clamp(13px,2.2cqmin,16px);
        font-weight: 600;
        text-decoration: none;
        transition: transform .3s cubic-bezier(.25,.1,.25,1),box-shadow .3s cubic-bezier(.25,.1,.25,1);
      }
      
      .n4-moles .n4-cta:hover {
        transform: translateY(-2px);
        box-shadow: 0 12px 32px -10px var(--accent);
      }
      
      .n4-moles .n4-cta:focus-visible {
        outline: 2px solid var(--accent);
        outline-offset: 3px;
      }
      
      .n4-moles .n4-stars,.n4-moles .n4-stars2 {
        position: absolute;
        inset: -4%;
        pointer-events: none;
      }
      
      .n4-moles .n4-stars {
        background-image: radial-gradient(1px 1px at 8% 12%,#fff 60%,transparent),radial-gradient(1px 1px at 22% 68%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 35% 24%,#fff 60%,transparent),radial-gradient(1px 1px at 48% 82%,#fff 60%,transparent),radial-gradient(1px 1px at 57% 9%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 66% 44%,#fff 60%,transparent),radial-gradient(1px 1px at 74% 72%,#fff 60%,transparent),radial-gradient(1px 1px at 86% 18%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 93% 58%,#fff 60%,transparent),radial-gradient(1px 1px at 14% 42%,#fff 60%,transparent),radial-gradient(1px 1px at 40% 55%,#fff 60%,transparent),radial-gradient(1px 1px at 81% 90%,#fff 60%,transparent),radial-gradient(1px 1px at 4% 88%,#fff 60%,transparent),radial-gradient(1px 1px at 62% 30%,#fff 60%,transparent);
        opacity: .75;
        animation: n4-moles-tw calc(5s / var(--k)) ease-in-out infinite alternate;
      }
      
      .n4-moles .n4-stars2 {
        background-image: radial-gradient(2px 2px at 18% 30%,rgba(255,255,255,.9) 50%,transparent),radial-gradient(1.5px 1.5px at 72% 20%,rgba(255,255,255,.8) 50%,transparent),radial-gradient(2px 2px at 30% 85%,rgba(255,255,255,.7) 50%,transparent),radial-gradient(1.5px 1.5px at 88% 70%,rgba(255,255,255,.8) 50%,transparent),radial-gradient(2px 2px at 52% 60%,rgba(255,255,255,.6) 50%,transparent),radial-gradient(1.5px 1.5px at 6% 55%,rgba(255,255,255,.8) 50%,transparent);
        opacity: .55;
        animation: n4-moles-tw calc(7s / var(--k)) ease-in-out infinite alternate-reverse;
      }
      
      .n4-moles [data-depth] {
        transition: transform .9s cubic-bezier(.2,.7,.2,1);
      }
      
      @keyframes n4-moles-tw {
        from {
          opacity: .3;
        }
      }
      
      @keyframes n4-moles-spin {
        to {
          transform: rotate(1turn);
        }
      }
      
      @keyframes n4-moles-fade {
        from {
          opacity: 0;
          transform: translateY(10px);
        }
      }
      
      @media (prefers-reduced-motion:reduce) {
        .n4-moles *,.n4-moles *::before,.n4-moles *::after {
          animation: none!important;
          transition: none!important;
        }
      }
      
      .n4-moles {
        background: radial-gradient(90% 45% at 50% 0,#eef9e2,transparent 75%),linear-gradient(#c7e7ab,#8fca66 55%,#67a845);
        color: #17330f;
      }
      
      .n4-moles .n4-lawn {
        width: min(60cqmin,420px);
        font-size: min(2cqmin,14px);
        margin-bottom: 1.2cqmin;
        padding: 1em 1.4em .8em;
        border-radius: 1.6em;
        background: repeating-linear-gradient(100deg,rgba(255,255,255,.07) 0 .3em,transparent .3em .9em),radial-gradient(120% 90% at 50% 0,#7cc95a,#4c9433);
        box-shadow: inset 0 .3em 0 rgba(255,255,255,.28),inset 0 -.5em 1em rgba(0,0,0,.2),0 1.4em 2em -1.2em rgba(23,51,15,.6);
      }
      
      .n4-moles .n4-holes {
        display: grid;
        grid-template-columns: repeat(3,1fr);
        gap: .4em 1.4em;
      }
      
      .n4-moles .n4-hole {
        position: relative;
        height: 7em;
        padding: 0;
        border: 0;
        border-radius: 1em;
        background: none;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
      }
      
      .n4-moles .n4-hole::before {
        content: "";
        position: absolute;
        left: 6%;
        right: 6%;
        bottom: .3em;
        height: 2.6em;
        border-radius: 50%;
        background: radial-gradient(closest-side,#1f1005 50%,#4a2e16 72%,#7a5230 94%,transparent);
        transition: filter .2s;
      }
      
      .n4-moles .n4-hole::after {
        content: "";
        position: absolute;
        z-index: 2;
        left: 6%;
        right: 6%;
        bottom: .3em;
        height: 2.6em;
        border-radius: 50%;
        box-shadow: inset 0 -.5em 0 #8a5c35;
        pointer-events: none;
      }
      
      .n4-moles .n4-hole:hover::before {
        filter: brightness(1.35);
      }
      
      .n4-moles .n4-hole:focus-visible {
        outline: 2px solid #fff;
        outline-offset: 2px;
      }
      
      .n4-moles .n4-pit {
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
        bottom: 1.6em;
        overflow: hidden;
        z-index: 1;
      }
      
      .n4-moles .n4-mole {
        position: absolute;
        left: 22%;
        right: 22%;
        bottom: 0;
        height: 5em;
        border-radius: 50% 50% 38% 38%/62% 62% 30% 30%;
        background: radial-gradient(circle at 37% 33%,#111 0 .2em,transparent .24em),radial-gradient(circle at 63% 33%,#111 0 .2em,transparent .24em),radial-gradient(circle at 37% 31%,#fff 0 .34em,transparent .38em),radial-gradient(circle at 63% 31%,#fff 0 .34em,transparent .38em),radial-gradient(ellipse .5em .38em at 50% 47%,#f49ac1 90%,transparent),radial-gradient(ellipse 1.4em 1em at 50% 54%,#d8b48a 92%,transparent),linear-gradient(#8a5a35,#5e3b20);
        transform: translateY(105%);
        transition: transform calc(.16s / var(--k)) cubic-bezier(.3,1.5,.6,1);
      }
      
      .n4-moles .n4-mole b {
        position: absolute;
        left: 50%;
        bottom: .55em;
        translate: -50% 0;
        padding: .14em .35em;
        border-radius: .15em;
        background: #f1d29a;
        color: #5b3a1e;
        font: 800 .8em/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
        rotate: -6deg;
        box-shadow: 0 .1em 0 #a9824b;
      }
      
      .n4-moles .n4-up .n4-mole {
        transform: translateY(6%);
      }
      
      .n4-moles .n4-hit .n4-mole {
        transform: translateY(42%) scale(1.12,.78);
        transition-duration: .08s;
      }
      
      .n4-moles .n4-count {
        display: flex;
        justify-content: center;
        align-items: baseline;
        gap: .6em;
        margin: .5em 0 0;
        font: 700 .95em/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
        text-transform: uppercase;
        letter-spacing: .14em;
        color: #f4ffe8;
      }
      
      .n4-moles .n4-count b {
        min-width: 1.6em;
        font-size: 1.7em;
        color: var(--accent);
        text-shadow: 0 .08em 0 rgba(0,0,0,.25);
      }
      
      .n4-moles .n4-tag {
        color: #2d5f1d;
      }
      
      .n4-moles .n4-title {
        font-size: clamp(20px,5cqmin,42px);
        font-weight: 800;
        letter-spacing: -.03em;
      }
      
      .n4-moles .n4-sub {
        color: #2f5223;
      }
      
      .n4-moles .n4-cta {
        background: #17330f;
        color: #f4ffe8;
      }
    </style>
  </head>
  <body>
    <main class="n4-moles">
      <div class="n4-copy">
        <div class="n4-lawn">
          <div class="n4-holes" role="group" aria-label="Garden burrows">
            <button class="n4-hole" type="button" aria-label="Burrow 1"><span class="n4-pit"><i class="n4-mole"><b translate="no">404</b></i></span></button>
            <button class="n4-hole" type="button" aria-label="Burrow 2"><span class="n4-pit"><i class="n4-mole"><b translate="no">404</b></i></span></button>
            <button class="n4-hole" type="button" aria-label="Burrow 3"><span class="n4-pit"><i class="n4-mole"><b translate="no">404</b></i></span></button>
            <button class="n4-hole" type="button" aria-label="Burrow 4"><span class="n4-pit"><i class="n4-mole"><b translate="no">404</b></i></span></button>
            <button class="n4-hole" type="button" aria-label="Burrow 5"><span class="n4-pit"><i class="n4-mole"><b translate="no">404</b></i></span></button>
            <button class="n4-hole" type="button" aria-label="Burrow 6"><span class="n4-pit"><i class="n4-mole"><b translate="no">404</b></i></span></button>
          </div>
          <p class="n4-count"><span>Caught</span><b aria-live="polite" translate="no">0</b></p>
        </div>
        <span class="n4-tag">Garden 404</span>
        <h1 class="n4-title">The page has gone underground.</h1>
        <p class="n4-sub">A mole dragged it into its burrow. Try to catch it or go back home the usual way.</p>
        <a class="n4-cta" href="/">Back to home</a>
      </div>
    </main>
    <script>
      document.querySelectorAll(".n4-moles").forEach((el) => {
        const holes = Array.from(el.querySelectorAll(".n4-hole"));
        const out = el.querySelector(".n4-count b");
        const rm = matchMedia("(prefers-reduced-motion: reduce)").matches;
        const k = parseFloat(getComputedStyle(el).getPropertyValue("--k")) || 1;
        let cur = -1, n = 0, t1 = 0, t2 = 0;
        const pop = () => {
          let i = Math.floor(Math.random() * holes.length);
          if (i === cur) i = (i + 1) % holes.length;
          cur = i;
          holes[i].classList.add("n4-up");
          t1 = setTimeout(() => {
            holes[i].classList.remove("n4-up");
            cur = -1;
            t2 = setTimeout(pop, (300 + Math.random() * 500) / k);
          }, (900 + Math.random() * 400) / k);
        };
        holes.forEach((h, i) => h.addEventListener("click", () => {
          if (i !== cur) return;
          clearTimeout(t1);
          clearTimeout(t2);
          n++;
          out.textContent = String(n);
          h.classList.remove("n4-up");
          h.classList.add("n4-hit");
          cur = -1;
          t2 = setTimeout(() => { h.classList.remove("n4-hit"); pop(); }, 420 / k);
        }));
        t2 = setTimeout(pop, 600 / k);
      });
    </script>
  </body>
</html>
```

### CSS

```css
.n4-moles {
  --accent: #f4c430;
  --k: 1;
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  container-type: size;
  display: grid;
  place-items: center;
  background: #000;
  color: #f5f5f7;
  font-family: -apple-system,BlinkMacSystemFont,"SF Pro Display","Inter","Segoe UI",system-ui,sans-serif;
  -webkit-font-smoothing: antialiased;
  text-align: center;
  line-height: 1.4;
}

.n4-moles *,.n4-moles *::before,.n4-moles *::after {
  box-sizing: border-box;
}

.n4-moles .n4-copy {
  position: relative;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.6cqmin;
  width: 100%;
  max-width: 680px;
  padding: 0 6cqw;
}

.n4-moles .n4-title {
  margin: 0;
  font-size: clamp(17px,4.2cqmin,36px);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.15;
  text-wrap: balance;
}

.n4-moles .n4-sub {
  margin: 0;
  max-width: 34em;
  font-size: clamp(13px,2.4cqmin,18px);
  color: #a1a1a6;
  text-wrap: balance;
}

.n4-moles .n4-tag {
  font: 600 clamp(10px,1.9cqmin,13px)/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
}

.n4-moles .n4-cta {
  margin-top: 1.8cqmin;
  display: inline-flex;
  align-items: center;
  gap: .5em;
  padding: .85em 1.5em;
  border-radius: 999px;
  background: #f5f5f7;
  color: #000;
  font-size: clamp(13px,2.2cqmin,16px);
  font-weight: 600;
  text-decoration: none;
  transition: transform .3s cubic-bezier(.25,.1,.25,1),box-shadow .3s cubic-bezier(.25,.1,.25,1);
}

.n4-moles .n4-cta:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 32px -10px var(--accent);
}

.n4-moles .n4-cta:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.n4-moles .n4-stars,.n4-moles .n4-stars2 {
  position: absolute;
  inset: -4%;
  pointer-events: none;
}

.n4-moles .n4-stars {
  background-image: radial-gradient(1px 1px at 8% 12%,#fff 60%,transparent),radial-gradient(1px 1px at 22% 68%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 35% 24%,#fff 60%,transparent),radial-gradient(1px 1px at 48% 82%,#fff 60%,transparent),radial-gradient(1px 1px at 57% 9%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 66% 44%,#fff 60%,transparent),radial-gradient(1px 1px at 74% 72%,#fff 60%,transparent),radial-gradient(1px 1px at 86% 18%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 93% 58%,#fff 60%,transparent),radial-gradient(1px 1px at 14% 42%,#fff 60%,transparent),radial-gradient(1px 1px at 40% 55%,#fff 60%,transparent),radial-gradient(1px 1px at 81% 90%,#fff 60%,transparent),radial-gradient(1px 1px at 4% 88%,#fff 60%,transparent),radial-gradient(1px 1px at 62% 30%,#fff 60%,transparent);
  opacity: .75;
  animation: n4-moles-tw calc(5s / var(--k)) ease-in-out infinite alternate;
}

.n4-moles .n4-stars2 {
  background-image: radial-gradient(2px 2px at 18% 30%,rgba(255,255,255,.9) 50%,transparent),radial-gradient(1.5px 1.5px at 72% 20%,rgba(255,255,255,.8) 50%,transparent),radial-gradient(2px 2px at 30% 85%,rgba(255,255,255,.7) 50%,transparent),radial-gradient(1.5px 1.5px at 88% 70%,rgba(255,255,255,.8) 50%,transparent),radial-gradient(2px 2px at 52% 60%,rgba(255,255,255,.6) 50%,transparent),radial-gradient(1.5px 1.5px at 6% 55%,rgba(255,255,255,.8) 50%,transparent);
  opacity: .55;
  animation: n4-moles-tw calc(7s / var(--k)) ease-in-out infinite alternate-reverse;
}

.n4-moles [data-depth] {
  transition: transform .9s cubic-bezier(.2,.7,.2,1);
}

@keyframes n4-moles-tw {
  from {
    opacity: .3;
  }
}

@keyframes n4-moles-spin {
  to {
    transform: rotate(1turn);
  }
}

@keyframes n4-moles-fade {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}

@media (prefers-reduced-motion:reduce) {
  .n4-moles *,.n4-moles *::before,.n4-moles *::after {
    animation: none!important;
    transition: none!important;
  }
}

.n4-moles {
  background: radial-gradient(90% 45% at 50% 0,#eef9e2,transparent 75%),linear-gradient(#c7e7ab,#8fca66 55%,#67a845);
  color: #17330f;
}

.n4-moles .n4-lawn {
  width: min(60cqmin,420px);
  font-size: min(2cqmin,14px);
  margin-bottom: 1.2cqmin;
  padding: 1em 1.4em .8em;
  border-radius: 1.6em;
  background: repeating-linear-gradient(100deg,rgba(255,255,255,.07) 0 .3em,transparent .3em .9em),radial-gradient(120% 90% at 50% 0,#7cc95a,#4c9433);
  box-shadow: inset 0 .3em 0 rgba(255,255,255,.28),inset 0 -.5em 1em rgba(0,0,0,.2),0 1.4em 2em -1.2em rgba(23,51,15,.6);
}

.n4-moles .n4-holes {
  display: grid;
  grid-template-columns: repeat(3,1fr);
  gap: .4em 1.4em;
}

.n4-moles .n4-hole {
  position: relative;
  height: 7em;
  padding: 0;
  border: 0;
  border-radius: 1em;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.n4-moles .n4-hole::before {
  content: "";
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: .3em;
  height: 2.6em;
  border-radius: 50%;
  background: radial-gradient(closest-side,#1f1005 50%,#4a2e16 72%,#7a5230 94%,transparent);
  transition: filter .2s;
}

.n4-moles .n4-hole::after {
  content: "";
  position: absolute;
  z-index: 2;
  left: 6%;
  right: 6%;
  bottom: .3em;
  height: 2.6em;
  border-radius: 50%;
  box-shadow: inset 0 -.5em 0 #8a5c35;
  pointer-events: none;
}

.n4-moles .n4-hole:hover::before {
  filter: brightness(1.35);
}

.n4-moles .n4-hole:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.n4-moles .n4-pit {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 1.6em;
  overflow: hidden;
  z-index: 1;
}

.n4-moles .n4-mole {
  position: absolute;
  left: 22%;
  right: 22%;
  bottom: 0;
  height: 5em;
  border-radius: 50% 50% 38% 38%/62% 62% 30% 30%;
  background: radial-gradient(circle at 37% 33%,#111 0 .2em,transparent .24em),radial-gradient(circle at 63% 33%,#111 0 .2em,transparent .24em),radial-gradient(circle at 37% 31%,#fff 0 .34em,transparent .38em),radial-gradient(circle at 63% 31%,#fff 0 .34em,transparent .38em),radial-gradient(ellipse .5em .38em at 50% 47%,#f49ac1 90%,transparent),radial-gradient(ellipse 1.4em 1em at 50% 54%,#d8b48a 92%,transparent),linear-gradient(#8a5a35,#5e3b20);
  transform: translateY(105%);
  transition: transform calc(.16s / var(--k)) cubic-bezier(.3,1.5,.6,1);
}

.n4-moles .n4-mole b {
  position: absolute;
  left: 50%;
  bottom: .55em;
  translate: -50% 0;
  padding: .14em .35em;
  border-radius: .15em;
  background: #f1d29a;
  color: #5b3a1e;
  font: 800 .8em/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  rotate: -6deg;
  box-shadow: 0 .1em 0 #a9824b;
}

.n4-moles .n4-up .n4-mole {
  transform: translateY(6%);
}

.n4-moles .n4-hit .n4-mole {
  transform: translateY(42%) scale(1.12,.78);
  transition-duration: .08s;
}

.n4-moles .n4-count {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: .6em;
  margin: .5em 0 0;
  font: 700 .95em/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: #f4ffe8;
}

.n4-moles .n4-count b {
  min-width: 1.6em;
  font-size: 1.7em;
  color: var(--accent);
  text-shadow: 0 .08em 0 rgba(0,0,0,.25);
}

.n4-moles .n4-tag {
  color: #2d5f1d;
}

.n4-moles .n4-title {
  font-size: clamp(20px,5cqmin,42px);
  font-weight: 800;
  letter-spacing: -.03em;
}

.n4-moles .n4-sub {
  color: #2f5223;
}

.n4-moles .n4-cta {
  background: #17330f;
  color: #f4ffe8;
}
```

### JavaScript

```js
document.querySelectorAll(".n4-moles").forEach((el) => {
  const holes = Array.from(el.querySelectorAll(".n4-hole"));
  const out = el.querySelector(".n4-count b");
  const rm = matchMedia("(prefers-reduced-motion: reduce)").matches;
  const k = parseFloat(getComputedStyle(el).getPropertyValue("--k")) || 1;
  let cur = -1, n = 0, t1 = 0, t2 = 0;
  const pop = () => {
    let i = Math.floor(Math.random() * holes.length);
    if (i === cur) i = (i + 1) % holes.length;
    cur = i;
    holes[i].classList.add("n4-up");
    t1 = setTimeout(() => {
      holes[i].classList.remove("n4-up");
      cur = -1;
      t2 = setTimeout(pop, (300 + Math.random() * 500) / k);
    }, (900 + Math.random() * 400) / k);
  };
  holes.forEach((h, i) => h.addEventListener("click", () => {
    if (i !== cur) return;
    clearTimeout(t1);
    clearTimeout(t2);
    n++;
    out.textContent = String(n);
    h.classList.remove("n4-up");
    h.classList.add("n4-hit");
    cur = -1;
    t2 = setTimeout(() => { h.classList.remove("n4-hit"); pop(); }, 420 / k);
  }));
  t2 = setTimeout(pop, 600 / k);
});
```

### React

```tsx
// @ts-nocheck: setup() es JavaScript del DOM sin tipos.
import { useEffect, useRef } from "react";

const css = `
.n4-moles {
  --accent: #f4c430;
  --k: 1;
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  container-type: size;
  display: grid;
  place-items: center;
  background: #000;
  color: #f5f5f7;
  font-family: -apple-system,BlinkMacSystemFont,"SF Pro Display","Inter","Segoe UI",system-ui,sans-serif;
  -webkit-font-smoothing: antialiased;
  text-align: center;
  line-height: 1.4;
}

.n4-moles *,.n4-moles *::before,.n4-moles *::after {
  box-sizing: border-box;
}

.n4-moles .n4-copy {
  position: relative;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.6cqmin;
  width: 100%;
  max-width: 680px;
  padding: 0 6cqw;
}

.n4-moles .n4-title {
  margin: 0;
  font-size: clamp(17px,4.2cqmin,36px);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.15;
  text-wrap: balance;
}

.n4-moles .n4-sub {
  margin: 0;
  max-width: 34em;
  font-size: clamp(13px,2.4cqmin,18px);
  color: #a1a1a6;
  text-wrap: balance;
}

.n4-moles .n4-tag {
  font: 600 clamp(10px,1.9cqmin,13px)/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
}

.n4-moles .n4-cta {
  margin-top: 1.8cqmin;
  display: inline-flex;
  align-items: center;
  gap: .5em;
  padding: .85em 1.5em;
  border-radius: 999px;
  background: #f5f5f7;
  color: #000;
  font-size: clamp(13px,2.2cqmin,16px);
  font-weight: 600;
  text-decoration: none;
  transition: transform .3s cubic-bezier(.25,.1,.25,1),box-shadow .3s cubic-bezier(.25,.1,.25,1);
}

.n4-moles .n4-cta:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 32px -10px var(--accent);
}

.n4-moles .n4-cta:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.n4-moles .n4-stars,.n4-moles .n4-stars2 {
  position: absolute;
  inset: -4%;
  pointer-events: none;
}

.n4-moles .n4-stars {
  background-image: radial-gradient(1px 1px at 8% 12%,#fff 60%,transparent),radial-gradient(1px 1px at 22% 68%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 35% 24%,#fff 60%,transparent),radial-gradient(1px 1px at 48% 82%,#fff 60%,transparent),radial-gradient(1px 1px at 57% 9%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 66% 44%,#fff 60%,transparent),radial-gradient(1px 1px at 74% 72%,#fff 60%,transparent),radial-gradient(1px 1px at 86% 18%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 93% 58%,#fff 60%,transparent),radial-gradient(1px 1px at 14% 42%,#fff 60%,transparent),radial-gradient(1px 1px at 40% 55%,#fff 60%,transparent),radial-gradient(1px 1px at 81% 90%,#fff 60%,transparent),radial-gradient(1px 1px at 4% 88%,#fff 60%,transparent),radial-gradient(1px 1px at 62% 30%,#fff 60%,transparent);
  opacity: .75;
  animation: n4-moles-tw calc(5s / var(--k)) ease-in-out infinite alternate;
}

.n4-moles .n4-stars2 {
  background-image: radial-gradient(2px 2px at 18% 30%,rgba(255,255,255,.9) 50%,transparent),radial-gradient(1.5px 1.5px at 72% 20%,rgba(255,255,255,.8) 50%,transparent),radial-gradient(2px 2px at 30% 85%,rgba(255,255,255,.7) 50%,transparent),radial-gradient(1.5px 1.5px at 88% 70%,rgba(255,255,255,.8) 50%,transparent),radial-gradient(2px 2px at 52% 60%,rgba(255,255,255,.6) 50%,transparent),radial-gradient(1.5px 1.5px at 6% 55%,rgba(255,255,255,.8) 50%,transparent);
  opacity: .55;
  animation: n4-moles-tw calc(7s / var(--k)) ease-in-out infinite alternate-reverse;
}

.n4-moles [data-depth] {
  transition: transform .9s cubic-bezier(.2,.7,.2,1);
}

@keyframes n4-moles-tw {
  from {
    opacity: .3;
  }
}

@keyframes n4-moles-spin {
  to {
    transform: rotate(1turn);
  }
}

@keyframes n4-moles-fade {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}

@media (prefers-reduced-motion:reduce) {
  .n4-moles *,.n4-moles *::before,.n4-moles *::after {
    animation: none!important;
    transition: none!important;
  }
}

.n4-moles {
  background: radial-gradient(90% 45% at 50% 0,#eef9e2,transparent 75%),linear-gradient(#c7e7ab,#8fca66 55%,#67a845);
  color: #17330f;
}

.n4-moles .n4-lawn {
  width: min(60cqmin,420px);
  font-size: min(2cqmin,14px);
  margin-bottom: 1.2cqmin;
  padding: 1em 1.4em .8em;
  border-radius: 1.6em;
  background: repeating-linear-gradient(100deg,rgba(255,255,255,.07) 0 .3em,transparent .3em .9em),radial-gradient(120% 90% at 50% 0,#7cc95a,#4c9433);
  box-shadow: inset 0 .3em 0 rgba(255,255,255,.28),inset 0 -.5em 1em rgba(0,0,0,.2),0 1.4em 2em -1.2em rgba(23,51,15,.6);
}

.n4-moles .n4-holes {
  display: grid;
  grid-template-columns: repeat(3,1fr);
  gap: .4em 1.4em;
}

.n4-moles .n4-hole {
  position: relative;
  height: 7em;
  padding: 0;
  border: 0;
  border-radius: 1em;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.n4-moles .n4-hole::before {
  content: "";
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: .3em;
  height: 2.6em;
  border-radius: 50%;
  background: radial-gradient(closest-side,#1f1005 50%,#4a2e16 72%,#7a5230 94%,transparent);
  transition: filter .2s;
}

.n4-moles .n4-hole::after {
  content: "";
  position: absolute;
  z-index: 2;
  left: 6%;
  right: 6%;
  bottom: .3em;
  height: 2.6em;
  border-radius: 50%;
  box-shadow: inset 0 -.5em 0 #8a5c35;
  pointer-events: none;
}

.n4-moles .n4-hole:hover::before {
  filter: brightness(1.35);
}

.n4-moles .n4-hole:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.n4-moles .n4-pit {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 1.6em;
  overflow: hidden;
  z-index: 1;
}

.n4-moles .n4-mole {
  position: absolute;
  left: 22%;
  right: 22%;
  bottom: 0;
  height: 5em;
  border-radius: 50% 50% 38% 38%/62% 62% 30% 30%;
  background: radial-gradient(circle at 37% 33%,#111 0 .2em,transparent .24em),radial-gradient(circle at 63% 33%,#111 0 .2em,transparent .24em),radial-gradient(circle at 37% 31%,#fff 0 .34em,transparent .38em),radial-gradient(circle at 63% 31%,#fff 0 .34em,transparent .38em),radial-gradient(ellipse .5em .38em at 50% 47%,#f49ac1 90%,transparent),radial-gradient(ellipse 1.4em 1em at 50% 54%,#d8b48a 92%,transparent),linear-gradient(#8a5a35,#5e3b20);
  transform: translateY(105%);
  transition: transform calc(.16s / var(--k)) cubic-bezier(.3,1.5,.6,1);
}

.n4-moles .n4-mole b {
  position: absolute;
  left: 50%;
  bottom: .55em;
  translate: -50% 0;
  padding: .14em .35em;
  border-radius: .15em;
  background: #f1d29a;
  color: #5b3a1e;
  font: 800 .8em/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  rotate: -6deg;
  box-shadow: 0 .1em 0 #a9824b;
}

.n4-moles .n4-up .n4-mole {
  transform: translateY(6%);
}

.n4-moles .n4-hit .n4-mole {
  transform: translateY(42%) scale(1.12,.78);
  transition-duration: .08s;
}

.n4-moles .n4-count {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: .6em;
  margin: .5em 0 0;
  font: 700 .95em/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: #f4ffe8;
}

.n4-moles .n4-count b {
  min-width: 1.6em;
  font-size: 1.7em;
  color: var(--accent);
  text-shadow: 0 .08em 0 rgba(0,0,0,.25);
}

.n4-moles .n4-tag {
  color: #2d5f1d;
}

.n4-moles .n4-title {
  font-size: clamp(20px,5cqmin,42px);
  font-weight: 800;
  letter-spacing: -.03em;
}

.n4-moles .n4-sub {
  color: #2f5223;
}

.n4-moles .n4-cta {
  background: #17330f;
  color: #f4ffe8;
}
`;

// Parallax con el puntero: JavaScript del DOM, el mismo de la pestaña JS.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function setup(el: any) {
  const holes = Array.from(el.querySelectorAll(".n4-hole"));
  const out = el.querySelector(".n4-count b");
  const rm = matchMedia("(prefers-reduced-motion: reduce)").matches;
  const k = parseFloat(getComputedStyle(el).getPropertyValue("--k")) || 1;
  let cur = -1, n = 0, t1 = 0, t2 = 0;
  const pop = () => {
    let i = Math.floor(Math.random() * holes.length);
    if (i === cur) i = (i + 1) % holes.length;
    cur = i;
    holes[i].classList.add("n4-up");
    t1 = setTimeout(() => {
      holes[i].classList.remove("n4-up");
      cur = -1;
      t2 = setTimeout(pop, (300 + Math.random() * 500) / k);
    }, (900 + Math.random() * 400) / k);
  };
  holes.forEach((h, i) => h.addEventListener("click", () => {
    if (i !== cur) return;
    clearTimeout(t1);
    clearTimeout(t2);
    n++;
    out.textContent = String(n);
    h.classList.remove("n4-up");
    h.classList.add("n4-hit");
    cur = -1;
    t2 = setTimeout(() => { h.classList.remove("n4-hit"); pop(); }, 420 / k);
  }));
  t2 = setTimeout(pop, 600 / k);
  return () => { clearTimeout(t1); clearTimeout(t2); };
}

export default function NotFoundMoles() {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const el = ref.current?.firstElementChild;
    return el ? setup(el) : undefined;
  }, []);

  return (
    <>
      <style>{css}</style>
      <div ref={ref}>
        <main className="n4-moles">
          <div className="n4-copy">
            <div className="n4-lawn">
              <div className="n4-holes" role="group" aria-label="Garden burrows">
                <button className="n4-hole" type="button" aria-label="Burrow 1"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
                <button className="n4-hole" type="button" aria-label="Burrow 2"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
                <button className="n4-hole" type="button" aria-label="Burrow 3"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
                <button className="n4-hole" type="button" aria-label="Burrow 4"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
                <button className="n4-hole" type="button" aria-label="Burrow 5"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
                <button className="n4-hole" type="button" aria-label="Burrow 6"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
              </div>
              <p className="n4-count"><span>Caught</span><b aria-live="polite" translate="no">0</b></p>
            </div>
            <span className="n4-tag">Garden 404</span>
            <h1 className="n4-title">The page has gone underground.</h1>
            <p className="n4-sub">A mole dragged it into its burrow. Try to catch it or go back home the usual way.</p>
            <a className="n4-cta" href="/">Back to home</a>
          </div>
        </main>
      </div>
    </>
  );
}
```

## Prompt for AI assistants

Paste this into ChatGPT, Claude, Cursor, v0 or Lovable to adapt the block to your stack (Tailwind, Vue, Svelte…):

````text
I want to add the “Whack a mole 404” block (404) from AIMRAN Library to my project.

## What it is
A lawn with six burrows where a mole holding a 404 sign pops up; tap it in time to score a point.

## Chosen settings
- Accent color: #f4c430
- Speed: 1x (from 0.5 to 2x)
- Title: "La página se ha escondido bajo tierra."
- Message: "Un topo se la ha llevado a su madriguera. Intenta atraparlo o vuelve al inicio por el camino de siempre."
- Button: "Volver al inicio"

## What I need
1. Add it to my project with the same look and animation as the reference code: same sizes, colours, radii, shadows, timings and easing.
2. It is built with plain HTML and CSS (the reference wraps it in a React component with its CSS). If my project uses something else (Vue, Svelte, Astro, plain HTML…), translate it without losing any behaviour. If I use Tailwind, turn the styles into classes; if not, keep the CSS in its own file.
3. Expose the settings above as props (or CSS variables) with those values as defaults.
4. Make it work well on phones: nothing that depends only on hover, touch targets of at least 44 px and no overflow on 320 px screens.
5. Make it look right in light and dark mode.
6. Keep it accessible: semantic HTML, roles and aria-* where needed, visible focus and keyboard support.
7. Respect prefers-reduced-motion: with reduced motion, no big animations but the same end result.

## Reference code
```tsx
// @ts-nocheck: setup() es JavaScript del DOM sin tipos.
import { useEffect, useRef } from "react";

const css = `
.n4-moles {
  --accent: #f4c430;
  --k: 1;
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  container-type: size;
  display: grid;
  place-items: center;
  background: #000;
  color: #f5f5f7;
  font-family: -apple-system,BlinkMacSystemFont,"SF Pro Display","Inter","Segoe UI",system-ui,sans-serif;
  -webkit-font-smoothing: antialiased;
  text-align: center;
  line-height: 1.4;
}

.n4-moles *,.n4-moles *::before,.n4-moles *::after {
  box-sizing: border-box;
}

.n4-moles .n4-copy {
  position: relative;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.6cqmin;
  width: 100%;
  max-width: 680px;
  padding: 0 6cqw;
}

.n4-moles .n4-title {
  margin: 0;
  font-size: clamp(17px,4.2cqmin,36px);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.15;
  text-wrap: balance;
}

.n4-moles .n4-sub {
  margin: 0;
  max-width: 34em;
  font-size: clamp(13px,2.4cqmin,18px);
  color: #a1a1a6;
  text-wrap: balance;
}

.n4-moles .n4-tag {
  font: 600 clamp(10px,1.9cqmin,13px)/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
}

.n4-moles .n4-cta {
  margin-top: 1.8cqmin;
  display: inline-flex;
  align-items: center;
  gap: .5em;
  padding: .85em 1.5em;
  border-radius: 999px;
  background: #f5f5f7;
  color: #000;
  font-size: clamp(13px,2.2cqmin,16px);
  font-weight: 600;
  text-decoration: none;
  transition: transform .3s cubic-bezier(.25,.1,.25,1),box-shadow .3s cubic-bezier(.25,.1,.25,1);
}

.n4-moles .n4-cta:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 32px -10px var(--accent);
}

.n4-moles .n4-cta:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.n4-moles .n4-stars,.n4-moles .n4-stars2 {
  position: absolute;
  inset: -4%;
  pointer-events: none;
}

.n4-moles .n4-stars {
  background-image: radial-gradient(1px 1px at 8% 12%,#fff 60%,transparent),radial-gradient(1px 1px at 22% 68%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 35% 24%,#fff 60%,transparent),radial-gradient(1px 1px at 48% 82%,#fff 60%,transparent),radial-gradient(1px 1px at 57% 9%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 66% 44%,#fff 60%,transparent),radial-gradient(1px 1px at 74% 72%,#fff 60%,transparent),radial-gradient(1px 1px at 86% 18%,#fff 60%,transparent),radial-gradient(1.5px 1.5px at 93% 58%,#fff 60%,transparent),radial-gradient(1px 1px at 14% 42%,#fff 60%,transparent),radial-gradient(1px 1px at 40% 55%,#fff 60%,transparent),radial-gradient(1px 1px at 81% 90%,#fff 60%,transparent),radial-gradient(1px 1px at 4% 88%,#fff 60%,transparent),radial-gradient(1px 1px at 62% 30%,#fff 60%,transparent);
  opacity: .75;
  animation: n4-moles-tw calc(5s / var(--k)) ease-in-out infinite alternate;
}

.n4-moles .n4-stars2 {
  background-image: radial-gradient(2px 2px at 18% 30%,rgba(255,255,255,.9) 50%,transparent),radial-gradient(1.5px 1.5px at 72% 20%,rgba(255,255,255,.8) 50%,transparent),radial-gradient(2px 2px at 30% 85%,rgba(255,255,255,.7) 50%,transparent),radial-gradient(1.5px 1.5px at 88% 70%,rgba(255,255,255,.8) 50%,transparent),radial-gradient(2px 2px at 52% 60%,rgba(255,255,255,.6) 50%,transparent),radial-gradient(1.5px 1.5px at 6% 55%,rgba(255,255,255,.8) 50%,transparent);
  opacity: .55;
  animation: n4-moles-tw calc(7s / var(--k)) ease-in-out infinite alternate-reverse;
}

.n4-moles [data-depth] {
  transition: transform .9s cubic-bezier(.2,.7,.2,1);
}

@keyframes n4-moles-tw {
  from {
    opacity: .3;
  }
}

@keyframes n4-moles-spin {
  to {
    transform: rotate(1turn);
  }
}

@keyframes n4-moles-fade {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}

@media (prefers-reduced-motion:reduce) {
  .n4-moles *,.n4-moles *::before,.n4-moles *::after {
    animation: none!important;
    transition: none!important;
  }
}

.n4-moles {
  background: radial-gradient(90% 45% at 50% 0,#eef9e2,transparent 75%),linear-gradient(#c7e7ab,#8fca66 55%,#67a845);
  color: #17330f;
}

.n4-moles .n4-lawn {
  width: min(60cqmin,420px);
  font-size: min(2cqmin,14px);
  margin-bottom: 1.2cqmin;
  padding: 1em 1.4em .8em;
  border-radius: 1.6em;
  background: repeating-linear-gradient(100deg,rgba(255,255,255,.07) 0 .3em,transparent .3em .9em),radial-gradient(120% 90% at 50% 0,#7cc95a,#4c9433);
  box-shadow: inset 0 .3em 0 rgba(255,255,255,.28),inset 0 -.5em 1em rgba(0,0,0,.2),0 1.4em 2em -1.2em rgba(23,51,15,.6);
}

.n4-moles .n4-holes {
  display: grid;
  grid-template-columns: repeat(3,1fr);
  gap: .4em 1.4em;
}

.n4-moles .n4-hole {
  position: relative;
  height: 7em;
  padding: 0;
  border: 0;
  border-radius: 1em;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.n4-moles .n4-hole::before {
  content: "";
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: .3em;
  height: 2.6em;
  border-radius: 50%;
  background: radial-gradient(closest-side,#1f1005 50%,#4a2e16 72%,#7a5230 94%,transparent);
  transition: filter .2s;
}

.n4-moles .n4-hole::after {
  content: "";
  position: absolute;
  z-index: 2;
  left: 6%;
  right: 6%;
  bottom: .3em;
  height: 2.6em;
  border-radius: 50%;
  box-shadow: inset 0 -.5em 0 #8a5c35;
  pointer-events: none;
}

.n4-moles .n4-hole:hover::before {
  filter: brightness(1.35);
}

.n4-moles .n4-hole:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.n4-moles .n4-pit {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 1.6em;
  overflow: hidden;
  z-index: 1;
}

.n4-moles .n4-mole {
  position: absolute;
  left: 22%;
  right: 22%;
  bottom: 0;
  height: 5em;
  border-radius: 50% 50% 38% 38%/62% 62% 30% 30%;
  background: radial-gradient(circle at 37% 33%,#111 0 .2em,transparent .24em),radial-gradient(circle at 63% 33%,#111 0 .2em,transparent .24em),radial-gradient(circle at 37% 31%,#fff 0 .34em,transparent .38em),radial-gradient(circle at 63% 31%,#fff 0 .34em,transparent .38em),radial-gradient(ellipse .5em .38em at 50% 47%,#f49ac1 90%,transparent),radial-gradient(ellipse 1.4em 1em at 50% 54%,#d8b48a 92%,transparent),linear-gradient(#8a5a35,#5e3b20);
  transform: translateY(105%);
  transition: transform calc(.16s / var(--k)) cubic-bezier(.3,1.5,.6,1);
}

.n4-moles .n4-mole b {
  position: absolute;
  left: 50%;
  bottom: .55em;
  translate: -50% 0;
  padding: .14em .35em;
  border-radius: .15em;
  background: #f1d29a;
  color: #5b3a1e;
  font: 800 .8em/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  rotate: -6deg;
  box-shadow: 0 .1em 0 #a9824b;
}

.n4-moles .n4-up .n4-mole {
  transform: translateY(6%);
}

.n4-moles .n4-hit .n4-mole {
  transform: translateY(42%) scale(1.12,.78);
  transition-duration: .08s;
}

.n4-moles .n4-count {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: .6em;
  margin: .5em 0 0;
  font: 700 .95em/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: #f4ffe8;
}

.n4-moles .n4-count b {
  min-width: 1.6em;
  font-size: 1.7em;
  color: var(--accent);
  text-shadow: 0 .08em 0 rgba(0,0,0,.25);
}

.n4-moles .n4-tag {
  color: #2d5f1d;
}

.n4-moles .n4-title {
  font-size: clamp(20px,5cqmin,42px);
  font-weight: 800;
  letter-spacing: -.03em;
}

.n4-moles .n4-sub {
  color: #2f5223;
}

.n4-moles .n4-cta {
  background: #17330f;
  color: #f4ffe8;
}
`;

// Parallax con el puntero: JavaScript del DOM, el mismo de la pestaña JS.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function setup(el: any) {
  const holes = Array.from(el.querySelectorAll(".n4-hole"));
  const out = el.querySelector(".n4-count b");
  const rm = matchMedia("(prefers-reduced-motion: reduce)").matches;
  const k = parseFloat(getComputedStyle(el).getPropertyValue("--k")) || 1;
  let cur = -1, n = 0, t1 = 0, t2 = 0;
  const pop = () => {
    let i = Math.floor(Math.random() * holes.length);
    if (i === cur) i = (i + 1) % holes.length;
    cur = i;
    holes[i].classList.add("n4-up");
    t1 = setTimeout(() => {
      holes[i].classList.remove("n4-up");
      cur = -1;
      t2 = setTimeout(pop, (300 + Math.random() * 500) / k);
    }, (900 + Math.random() * 400) / k);
  };
  holes.forEach((h, i) => h.addEventListener("click", () => {
    if (i !== cur) return;
    clearTimeout(t1);
    clearTimeout(t2);
    n++;
    out.textContent = String(n);
    h.classList.remove("n4-up");
    h.classList.add("n4-hit");
    cur = -1;
    t2 = setTimeout(() => { h.classList.remove("n4-hit"); pop(); }, 420 / k);
  }));
  t2 = setTimeout(pop, 600 / k);
  return () => { clearTimeout(t1); clearTimeout(t2); };
}

export default function NotFoundMoles() {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const el = ref.current?.firstElementChild;
    return el ? setup(el) : undefined;
  }, []);

  return (
    <>
      <style>{css}</style>
      <div ref={ref}>
        <main className="n4-moles">
          <div className="n4-copy">
            <div className="n4-lawn">
              <div className="n4-holes" role="group" aria-label="Garden burrows">
                <button className="n4-hole" type="button" aria-label="Burrow 1"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
                <button className="n4-hole" type="button" aria-label="Burrow 2"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
                <button className="n4-hole" type="button" aria-label="Burrow 3"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
                <button className="n4-hole" type="button" aria-label="Burrow 4"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
                <button className="n4-hole" type="button" aria-label="Burrow 5"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
                <button className="n4-hole" type="button" aria-label="Burrow 6"><span className="n4-pit"><i className="n4-mole"><b translate="no">404</b></i></span></button>
              </div>
              <p className="n4-count"><span>Caught</span><b aria-live="polite" translate="no">0</b></p>
            </div>
            <span className="n4-tag">Garden 404</span>
            <h1 className="n4-title">The page has gone underground.</h1>
            <p className="n4-sub">A mole dragged it into its burrow. Try to catch it or go back home the usual way.</p>
            <a className="n4-cta" href="/">Back to home</a>
          </div>
        </main>
      </div>
    </>
  );
}
```

Give me the complete final code, ready to paste, and tell me in one line where to put it in my project.
````
