Atrapados0

Jardín 404

La página se ha escondido bajo tierra.

Un topo se la ha llevado a su madriguera. Intenta atraparlo o vuelve al inicio por el camino de siempre.

Volver al inicio
HTML + CSS404

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.

Settings

1x

Code

<!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>

Prompt for AI

Paste it into ChatGPT, Claude or Cursor and it will adapt the block to your project with these settings, even if you don’t use React.

Markdown version with all the code, for AI assistants

More in 404

See all 404

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.