Caimán
La web de un bar: carta por categorías, ofertas y reservas.
- Astro 4
- CSS propio
- JS vanilla
- Canvas 2D
Caimán es la web de un bar y cachimbería: carta completa por categorías, ofertas, ubicación y un formulario de reserva. Astro con salida estática, sin ningún framework de interfaz y sin más dependencia de producción que el propio Astro. Hoy funciona en modo demo: el aviso del propio sitio explica que las funciones de contacto, WhatsApp y reserva están desactivadas porque el local cambió de propietarios.
Índice de la carta Carta de cachimbas Formulario de reserva Ubicación
Qué hay dentro
Trece páginas más un 404 propio: portada, índice de la carta, siete cartas por categoría (cachimbas, cócteles, combinados, cervezas, vinos, refrescos y batidos), ofertas, nosotros, ubicación y reservas. El índice de la carta se genera desde dos arrays declarados en el propio archivo —dos categorías destacadas con descripción y precio, cinco estándar— y se pinta con un map, así que añadir una categoría es añadir una línea. Las cartas de cada categoría sí están escritas a mano, con etiquetas de Top, Recomendado y Nuevo por producto; la de cachimbas es la más larga: veinticuatro mezclas tradicionales, tres premium, tres vapeadores y un upgrade. Todo cuelga de dos layouts, y la navegación entera —barra, dock móvil, pie, cada banner, el final de cada carta— empuja siempre al mismo sitio: reservas.
Un sistema de diseño a mano, sin framework
La hoja principal son 1.065 líneas de sistema de diseño propio: tokens en :root (los tres neones, el fondo, las tipografías, easing y radio), efectos neón, barra, tarjetas, formularios y cuatro puntos de ruptura, incluido un caso de móvil apaisado. A eso se suma una segunda hoja para las páginas de carta. No hay Tailwind ni Bootstrap: el package.json declara una sola dependencia, astro. Tampoco hay librería de iconos: los siete iconos de categoría van como SVG inline, y el logo se define una vez por página como sprite con degradado neón y se reutiliza por referencia. Lo único externo se carga por CDN y solo donde hace falta: Swiper, en la página de ofertas.
La reserva, que es lo que importa
El formulario pide nombre, teléfono, email, fecha, hora y número de personas. La hora está acotada al horario real del local y el número de comensales es un control de rango de 1 a 12 con una etiqueta que se actualiza en vivo y distingue singular de plural. Va sin validación nativa para controlarla desde JavaScript. El layout incluso esconde el dock flotante cuando estás en esa página, porque ahí el CTA ya es la página entera. Detrás no hay backend: el botón de enviar llama por onclick a la función de validación, que abre el modal de demo. Y eso está dicho en la propia página, con un aviso encima del formulario, no escondido.
Animación que se apaga sola
El archivo de scripts son 327 líneas de JavaScript vanilla en bloques independientes, cada uno con su guardia de salida si el elemento no está en la página. Lo primero que hace, antes de cualquier bloque, es leer prefers-reduced-motion y pointer: fine, y a partir de ahí todo lo vistoso está condicionado: el canvas de partículas —que está en la portada y también en el 404— pinta un único fotograma estático y no entra en el bucle de animación si el usuario pide menos movimiento, el contador de estadísticas salta directo al número final, y el tilt de tarjetas y los botones magnéticos ni se registran si no hay ratón. El modal de demo es un diálogo con aria-modal, trampa de tabulación en ambos sentidos, cierre con Escape y devolución del foco al elemento que lo abrió. Hay skip-link, foco visible con contorno cian y estado expandido anunciado en el menú y en cada pregunta del FAQ.
Detalles
Cero dependencias de interfaz
La única dependencia de producción es astro; lo de fuera entra por CDN y solo en la página que lo pide.
Sistema de diseño propio de más de mil líneas
Tokens en :root, efectos neón, componentes y cuatro puntos de ruptura escritos a mano, sin Tailwind ni Bootstrap.
Todo lo animado está condicionado
Se lee prefers-reduced-motion y pointer: fine antes de nada; el canvas pinta un fotograma estático en vez de entrar en bucle.
Modal accesible de verdad
Diálogo con aria-modal, trampa de tabulación en los dos sentidos, cierre con Escape y devolución del foco al botón que lo abrió.
Formulario de reserva completo sin backend
Rango de 1 a 12 con etiqueta viva, hora acotada al horario del local y aviso en pantalla de que las reservas reales están desactivadas.
¿Tienes algo parecido entre manos?
Si necesitas algo así —una landing, una web, un ERP o una herramienta que no encuentras hecha—, cuéntanoslo y te contestamos con cómo lo haríamos, cuánto llevaría y qué costaría.
Cuéntanos tu proyecto