aeworks.tech/lab/precios-odometro
← AE Lab

Precios con cuentakilómetros

14 oct 2026· nivel mediopreciosodómetroscroll-snap

Tabla de tres planes con interruptor Mensual / Anual: cada cifra del precio rueda como un cuentakilómetros mecánico con rebote, cae una etiqueta «-20 %» con muelle y el plan recomendado lleva un brillo que recorre su borde. En el móvil, las tarjetas son un carrusel con scroll-snap.

// CÓMO ESTÁ HECHO

  1. Cada dígito es una ventana de una cifra de alto con overflow oculto, y detrás una tira con 0-9 repetido tres veces que se desplaza con translateY.
  2. Al cambiar de periodo la tira gira una vuelta entera hasta su cifra con una curva cubic-bezier que se pasa y vuelve (el rebote), con retraso escalonado por dígito y por tarjeta; al acabar salta sin animación a la vuelta del medio.
  3. La etiqueta «-20 %» cae con una animación de keyframes que imita un muelle (cae, rebota y se asienta ladeada).
  4. El brillo del recomendado es un cuadrado con degradado cónico que gira detrás de la tarjeta y una capa interior que lo tapa dejando sólo 2 px de borde.
  5. En móvil la rejilla pasa a flex con overflow-x y scroll-snap-type, con puntos sincronizados; un interruptor role=switch accesible por teclado y prefers-reduced-motion sin giros.

// EL CÓDIGO

<main class="app" id="app">
  <header class="cabecera">
    <span class="marca mono">Forja · club de entrenamiento</span>
    <h1>Entrena a tu ritmo</h1>
    <p>Sin matrícula. Cambia de plan cuando quieras.</p>
    <div class="periodo">
      <!-- Un solo botón con role="switch": Espacio / Intro lo cambian -->
      <button class="interruptor" id="interruptor" role="switch" aria-checked="false" aria-label="Pago anual">
        <span class="pildora" aria-hidden="true"></span>
        <span class="opcion mes">Mensual</span>
        <span class="opcion ano">Anual</span>
      </button>
      <span class="chapa" aria-hidden="true">-20 %</span>
    </div>
  </header>

  <ul class="planes" id="planes" aria-label="Planes"></ul>
  <nav class="puntos" id="puntos" aria-label="Ir al plan"></nav>
  <p class="oculto" id="aviso" aria-live="polite"></p>
</main>