Combinación: 4 · 0 · 4

Hemos abierto la caja y no hay nada.

La página que buscas no estaba guardada aquí. Prueba la combinación si no te lo crees, o vuelve al inicio.

Volver al inicio
HTML + CSS404

404 Caja fuerte

Una caja fuerte de acero con un dial que gira arrastrando o con las flechas; con la combinación 4, 0, 4 se abre.

Ajustes

1x

Código

<!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 · Página no encontrada</title>
    <style>
      body { margin: 0; background: #000; }
      .n4-safe {
        --accent: #ffcc4d;
        --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-safe *,.n4-safe *::before,.n4-safe *::after {
        box-sizing: border-box;
      }
      
      .n4-safe .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-safe .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-safe .n4-sub {
        margin: 0;
        max-width: 34em;
        font-size: clamp(13px,2.4cqmin,18px);
        color: #a1a1a6;
        text-wrap: balance;
      }
      
      .n4-safe .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-safe .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-safe .n4-cta:hover {
        transform: translateY(-2px);
        box-shadow: 0 12px 32px -10px var(--accent);
      }
      
      .n4-safe .n4-cta:focus-visible {
        outline: 2px solid var(--accent);
        outline-offset: 3px;
      }
      
      .n4-safe .n4-stars,.n4-safe .n4-stars2 {
        position: absolute;
        inset: -4%;
        pointer-events: none;
      }
      
      .n4-safe .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-safe-tw calc(5s / var(--k)) ease-in-out infinite alternate;
      }
      
      .n4-safe .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-safe-tw calc(7s / var(--k)) ease-in-out infinite alternate-reverse;
      }
      
      .n4-safe [data-depth] {
        transition: transform .9s cubic-bezier(.2,.7,.2,1);
      }
      
      @keyframes n4-safe-tw {
        from {
          opacity: .3;
        }
      }
      
      @keyframes n4-safe-spin {
        to {
          transform: rotate(1turn);
        }
      }
      
      @keyframes n4-safe-fade {
        from {
          opacity: 0;
          transform: translateY(10px);
        }
      }
      
      @media (prefers-reduced-motion:reduce) {
        .n4-safe *,.n4-safe *::before,.n4-safe *::after {
          animation: none!important;
          transition: none!important;
        }
      }
      
      .n4-safe {
        background: radial-gradient(70% 60% at 50% 30%,#2d323a,#0d0f12 75%);
        color: #eef0f3;
      }
      
      .n4-safe .n4-vault {
        position: relative;
        width: 10em;
        height: 10em;
        font-size: min(4.3cqmin,30px);
        margin-bottom: 1.4cqmin;
        perspective: 40em;
      }
      
      .n4-safe .n4-inside {
        position: absolute;
        inset: .35em;
        display: grid;
        place-items: center;
        border-radius: .4em;
        background: linear-gradient(#0a0b0d,#1d2025);
        box-shadow: inset 0 0 1.4em #000;
      }
      
      .n4-safe .n4-shelf {
        position: absolute;
        left: 8%;
        right: 8%;
        top: 62%;
        height: .22em;
        background: #3a3f46;
        box-shadow: 0 .2em .3em rgba(0,0,0,.6);
      }
      
      .n4-safe .n4-note {
        position: relative;
        top: -.4em;
        margin: 0;
        padding: .5em .7em;
        rotate: -5deg;
        background: #fdf6d8;
        color: #3b3020;
        font: 500 .5em/1.2 "Segoe Print","Bradley Hand","Chalkboard SE","Comic Sans MS",cursive;
        box-shadow: 0 .3em .5em rgba(0,0,0,.5);
      }
      
      .n4-safe .n4-door {
        position: absolute;
        inset: 0;
        border-radius: .5em;
        transform-origin: 0 50%;
        background: radial-gradient(circle at 12% 12%,#7c848d 0 .1em,transparent .13em),radial-gradient(circle at 88% 12%,#7c848d 0 .1em,transparent .13em),radial-gradient(circle at 12% 88%,#7c848d 0 .1em,transparent .13em),radial-gradient(circle at 88% 88%,#7c848d 0 .1em,transparent .13em),linear-gradient(135deg,#5e656e,#30353b 45%,#474d55 70%,#23272c);
        box-shadow: inset 0 0 0 .1em #6f7780,inset 0 0 0 .35em #2a2e33,inset 0 0 0 .42em #5a6168,0 .6em 1em -.3em #000;
        transition: transform calc(1.1s / var(--k)) cubic-bezier(.5,0,.2,1);
      }
      
      .n4-safe .n4-open .n4-door {
        transform: rotateY(-80deg);
      }
      
      .n4-safe .n4-err .n4-door {
        animation: n4-safe-shake calc(.4s / var(--k));
      }
      
      .n4-safe .n4-hinge {
        position: absolute;
        left: -.16em;
        top: 1.5em;
        width: .32em;
        height: 1.5em;
        border-radius: .14em;
        background: linear-gradient(90deg,#383d43,#a3aab2,#383d43);
      }
      
      .n4-safe .n4-h2 {
        top: auto;
        bottom: 1.5em;
      }
      
      .n4-safe .n4-code {
        position: absolute;
        top: .75em;
        left: 50%;
        translate: -50% 0;
        display: flex;
        gap: .12em;
      }
      
      .n4-safe .n4-code b {
        display: grid;
        place-items: center;
        width: 1.15em;
        height: 1.4em;
        border-radius: .14em;
        background: #0b0c0e;
        color: var(--accent);
        font: 700 .55em/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
        box-shadow: inset 0 0 0 .08em #4a5058;
      }
      
      .n4-safe .n4-led {
        position: absolute;
        top: .95em;
        right: 1em;
        width: .32em;
        height: .32em;
        border-radius: 50%;
        background: #3a2a1a;
        box-shadow: inset 0 0 0 .04em #000;
      }
      
      .n4-safe .n4-err .n4-led {
        background: #ff4d4d;
        box-shadow: 0 0 .4em #ff4d4d;
      }
      
      .n4-safe .n4-open .n4-led {
        background: #4ade80;
        box-shadow: 0 0 .4em #4ade80;
      }
      
      .n4-safe .n4-mark {
        position: absolute;
        left: 50%;
        top: 2.15em;
        width: 0;
        height: 0;
        translate: -50% 0;
        border: .16em solid transparent;
        border-top: .24em solid var(--accent);
      }
      
      .n4-safe .n4-dial {
        position: absolute;
        left: 50%;
        top: 5.15em;
        width: 5.3em;
        height: 5.3em;
        translate: -50% -50%;
        border-radius: 50%;
        cursor: grab;
        touch-action: none;
      }
      
      .n4-safe .n4-dial:active {
        cursor: grabbing;
      }
      
      .n4-safe .n4-dial:focus-visible {
        outline: 2px solid var(--accent);
        outline-offset: .2em;
      }
      
      .n4-safe .n4-ring {
        position: absolute;
        inset: 0;
        border-radius: 50%;
        background: radial-gradient(circle,#c9ced4 0 44%,#7b828a 45% 47%,#17191c 48% 85%,transparent 86%),repeating-conic-gradient(#3a3e44 0 3deg,#7d848c 3deg 6deg);
        box-shadow: 0 .25em .45em rgba(0,0,0,.6);
        rotate: var(--rot,0deg);
        transition: rotate .25s cubic-bezier(.3,1.5,.5,1);
      }
      
      .n4-safe .n4-ring.n4-drag {
        transition: none;
      }
      
      .n4-safe .n4-ring b {
        position: absolute;
        left: 50%;
        top: 50%;
        display: grid;
        place-items: center;
        width: 1.4em;
        height: 1.4em;
        margin: -.7em;
        font: 700 .44em/1 ui-monospace,"SF Mono",Menlo,Consolas,monospace;
        color: #f2f4f7;
        transform: rotate(calc(var(--i) * 36deg)) translateY(-4.15em);
      }
      
      .n4-safe .n4-cap {
        position: absolute;
        inset: 32%;
        border-radius: 50%;
        background: repeating-conic-gradient(from 0deg,#aeb4bb 0 10deg,#dfe3e7 10deg 20deg);
        box-shadow: inset 0 0 0 .08em #8c939b,0 .08em .2em rgba(0,0,0,.4);
        pointer-events: none;
      }
      
      .n4-safe .n4-handle {
        position: absolute;
        right: .6em;
        top: 50%;
        width: .36em;
        height: 2.4em;
        translate: 0 -50%;
        border-radius: .2em;
        background: linear-gradient(90deg,#7d848c,#e3e6ea,#6d747c);
        box-shadow: 0 .1em .2em rgba(0,0,0,.5);
      }
      
      .n4-safe .n4-try {
        position: absolute;
        left: 50%;
        bottom: .62em;
        translate: -50% 0;
        padding: .6em 1.1em;
        border: 0;
        border-radius: 999px;
        cursor: pointer;
        font: 700 .4em/1 system-ui,sans-serif;
        letter-spacing: .06em;
        white-space: nowrap;
        color: #2a1d05;
        background: linear-gradient(#f6d985,#b98a26);
        box-shadow: 0 .2em 0 #6e5212;
        transition: transform .1s,box-shadow .1s,filter .2s;
      }
      
      .n4-safe .n4-try:hover {
        filter: brightness(1.08);
      }
      
      .n4-safe .n4-try:active {
        transform: translateY(.15em);
        box-shadow: 0 .05em 0 #6e5212;
      }
      
      .n4-safe .n4-try:focus-visible {
        outline: 2px solid var(--accent);
        outline-offset: 3px;
      }
      
      .n4-safe .n4-title {
        font-size: clamp(20px,5cqmin,42px);
        font-weight: 700;
        letter-spacing: -.025em;
      }
      
      .n4-safe .n4-sub {
        color: #a9b0b9;
      }
      
      .n4-safe .n4-cta {
        background: var(--accent);
        color: #1d1503;
      }
      
      .n4-safe .n4-sr {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
      }
      
      @keyframes n4-safe-shake {
        20%,60% {
          translate: -.14em 0;
        }
        40%,80% {
          translate: .14em 0;
        }
      }
    </style>
  </head>
  <body>
    <main class="n4-safe">
      <div class="n4-copy">
        <div class="n4-vault">
          <div class="n4-inside" aria-hidden="true"><i class="n4-shelf"></i><p class="n4-note">Aquí tampoco está.</p></div>
          <div class="n4-door">
            <i class="n4-hinge" aria-hidden="true"></i><i class="n4-hinge n4-h2" aria-hidden="true"></i>
            <div class="n4-code" aria-hidden="true" translate="no"><b>·</b><b>·</b><b>·</b></div>
            <i class="n4-led" aria-hidden="true"></i>
            <i class="n4-mark" aria-hidden="true"></i>
            <div class="n4-dial" role="slider" tabindex="0" aria-label="Dial de la combinación" aria-valuemin="0" aria-valuemax="9" aria-valuenow="0">
              <div class="n4-ring" aria-hidden="true" translate="no"><b style="--i:0">0</b><b style="--i:1">1</b><b style="--i:2">2</b><b style="--i:3">3</b><b style="--i:4">4</b><b style="--i:5">5</b><b style="--i:6">6</b><b style="--i:7">7</b><b style="--i:8">8</b><b style="--i:9">9</b></div>
              <i class="n4-cap" aria-hidden="true"></i>
            </div>
            <i class="n4-handle" aria-hidden="true"></i>
            <button class="n4-try" type="button">Marcar número</button>
          </div>
          <p class="n4-sr" aria-live="polite"></p>
        </div>
        <span class="n4-tag">Combinación: 4 · 0 · 4</span>
        <h1 class="n4-title">Hemos abierto la caja y no hay nada.</h1>
        <p class="n4-sub">La página que buscas no estaba guardada aquí. Prueba la combinación si no te lo crees, o vuelve al inicio.</p>
        <a class="n4-cta" href="/">Volver al inicio</a>
      </div>
    </main>
    <script>
      document.querySelectorAll(".n4-safe").forEach((el) => {
        const vault = el.querySelector(".n4-vault");
        const dial = el.querySelector(".n4-dial");
        const ring = el.querySelector(".n4-ring");
        const slots = el.querySelectorAll(".n4-code b");
        const btn = el.querySelector(".n4-try");
        const live = el.querySelector(".n4-sr");
        const LABEL = btn.textContent;
        let rot = 0, code = [], open = false, drag = null, timer = 0;
        const val = () => ((Math.round(-rot / 36) % 10) + 10) % 10;
        const paint = () => {
          ring.style.setProperty("--rot", rot + "deg");
          dial.setAttribute("aria-valuenow", String(val()));
          slots.forEach((s, i) => { s.textContent = code[i] === undefined ? "·" : String(code[i]); });
        };
        const step = (d) => { rot -= d * 36; paint(); };
        const press = () => {
          clearTimeout(timer);
          if (open) {
            open = false;
            code = [];
            vault.classList.remove("n4-open");
            btn.textContent = LABEL;
            live.textContent = "";
            paint();
          } else {
            code.push(val());
            paint();
            if (code.length === 3 && code.join("") === "404") {
              open = true;
              vault.classList.add("n4-open");
              btn.textContent = "Cerrar la puerta";
              live.textContent = "Caja abierta: está vacía";
            } else if (code.length === 3) {
              vault.classList.add("n4-err");
              live.textContent = "Combinación incorrecta";
              timer = setTimeout(() => { vault.classList.remove("n4-err"); code = []; paint(); }, 900);
            }
          }
        };
        dial.addEventListener("keydown", (e) => {
          if (e.key === "ArrowRight" || e.key === "ArrowUp") { e.preventDefault(); step(1); }
          else if (e.key === "ArrowLeft" || e.key === "ArrowDown") { e.preventDefault(); step(-1); }
          else if (e.key === "Enter" || e.key === " ") { e.preventDefault(); press(); }
        });
        const angle = (e) => {
          const r = dial.getBoundingClientRect();
          return (Math.atan2(e.clientX - r.left - r.width / 2, r.top + r.height / 2 - e.clientY) * 180) / Math.PI;
        };
        dial.addEventListener("pointerdown", (e) => { drag = angle(e); dial.setPointerCapture(e.pointerId); ring.classList.add("n4-drag"); });
        dial.addEventListener("pointermove", (e) => {
          if (drag === null) return;
          const a = angle(e);
          let d = a - drag;
          if (d > 180) d -= 360;
          if (d < -180) d += 360;
          rot += d;
          drag = a;
          paint();
        });
        const end = () => {
          if (drag === null) return;
          drag = null;
          ring.classList.remove("n4-drag");
          rot = Math.round(rot / 36) * 36;
          paint();
        };
        dial.addEventListener("pointerup", end);
        dial.addEventListener("pointercancel", end);
        btn.addEventListener("click", press);
        paint();
      });
    </script>
  </body>
</html>

Prompt para IA

Pégalo en ChatGPT, Claude o Cursor y adaptará el bloque a tu proyecto con estos ajustes, aunque no uses React.

Versión Markdown con todo el código, para asistentes de IA

Más en 404

Ver todos: 404

Dónde usarlo

Esta página de error es un pequeño acertijo: una caja fuerte de acero con bisagras, remaches y un dial moleteado. El dial se gira arrastrándolo en círculo o con las flechas, el botón de latón marca cada número y la combinación 4, 0, 4 abre la puerta sobre un estante vacío.

El dial es un control deslizante accesible que anuncia su valor, los códigos erróneos hacen temblar la puerta y encienden un LED rojo, y la pista está justo debajo. Cambia el ámbar y enlaza el botón con tu portada.