El contexto de uso manda
Pantalla a distancia, una mano libre como mucho, conexión inestable y poco tiempo. Todo el diseño parte de ahí, no de una galería de pantallas bonitas.
Caso de estudio · Producto propio · 2026
De 10 a 25 minutos, armada con las pesas que tienes en casa y con el estudio que respalda cada bloque. Tú levantas; la app lleva el tiempo, las repeticiones y los descansos. Sin contraseñas, sin tienda de apps y sin prometerte lo que la ciencia no sostiene.
Las pantallas, de un vistazo








01 · Contexto y problema
KETTELBRO nace de una pregunta de producto: ¿cómo pasa alguien de un reto de 30 días a un hábito de entrenamiento sostenido, sin pensar qué toca hoy?
Según el documento de producto del repo, las personas a las que va dirigida vienen precisamente de un reto de 30 días, entrenan en casa o en un gimnasio pequeño con una a tres pesas rusas, y usan el teléfono mientras entrenan: con las manos con magnesia o sudadas, el móvil apoyado a metros de distancia y entre 10 y 45 minutos como mucho. Las apps genéricas de fitness suelen darles una lista de rutinas «inventadas», sin explicar por qué están ahí.
Pantalla a distancia, una mano libre como mucho, conexión inestable y poco tiempo. Todo el diseño parte de ahí, no de una galería de pantallas bonitas.
El posicionamiento declarado: un motor de programación determinista basado en protocolos documentados (Hardstyle, Girevoy Sport, periodización ondulante, RPE) en el que cada bloque puede citar su respaldo.
Nada de «tonificar» ni quema garantizada de calorías: las afirmaciones de salud se limitan a lo que la literatura respalda. Es una restricción de diseño, también para el copy.
Qué no sé (y no invento). El repositorio declara explícitamente que no hay testimonios, usuarios ni métricas reales. Por eso este caso habla de decisiones y de hipótesis, no de resultados de negocio.
02 · Usuarios y necesidades
No hice entrevistas para esta versión. Estas proto-personas son una síntesis de lo que dicen PRODUCT.md, la FAQ y el motor de rutinas del repo; sirven para decidir y están marcadas como hipótesis hasta validarlas con usuarios reales.
Terminó un reto de 30 días y no quiere volver a decidir cada mañana qué hacer. Necesita que alguien decida por ella y que la racha no se rompa por perder un día.
Fuente: Users en PRODUCT.md; «el día avanza al completar» en MOTOR-DE-RUTINAS.md.Entrena con una o dos pesas, con mala luz y el móvil lejos. Necesita números enormes, un toque, sonido y vibración y poder retomar si cierra la app a mitad de sesión.
Fuente: Operating Context en PRODUCT.md; borrador de sesión activa en la arquitectura de datos.Nunca ha tocado una pesa rusa y duda de su espalda. Necesita progresión sin swings al inicio, técnica a la vista y un cribado de salud, no promesas.
Fuente: FAQ de la landing (primeros 14 días sin swings; modo de cuidado lumbar).03 · Principios de diseño
El repo las enuncia como principios de producto. Las uso como criterio para explicar cada decisión de este caso.
1
Cada bloque puede explicar por qué está ahí.
2
Entrar con Google devuelve el estado exacto, offline o a mitad de sesión.
3
Legible a distancia, un toque, feedback sonoro y háptico.
4
Variedad con intención fisiológica.
5
Logros reales derivados de datos reales.
04 · Flujo y arquitectura de información
El flujo principal tiene cuatro pasos, y el segundo («cuéntanos de ti») se hace una sola vez. A partir de ahí, cada día es: abrir, ver la tarjeta, empezar.
La estructura sale de las rutas del repo (src/app). Hay una capa pública, pensada para que se pueda indexar y entender sin cuenta, y un área privada con cuatro destinos fijos en la barra inferior.
Público ├─ / landing: propuesta, cómo funciona, ciencia, FAQ, instalar ├─ /ciencia 74 referencias con diseño de estudio y nivel A-D └─ /guias técnica, pesos y rutinas Privado (tras Google) ├─ /bienvenida alta del perfil ├─ Tab bar: Hoy · Progreso · Metas · Perfil (+ /pesas) └─ /sesion acompañante en vivo, a pantalla completa
Decisión de IA: cuatro destinos, no seis. El día de hoy es la pantalla de aterrizaje; todo lo demás es consulta o ajuste. La sesión en curso queda fuera de la barra para que ninguna pestaña compita con el reloj.
Cómo se decide el contenido de «Hoy». El motor es puro: Día N → fase del mesociclo → enfoque del día → bloques → pasos. La semilla es UID + número de día, así que recargar o cambiar de teléfono da exactamente la misma tarjeta.
05 · Decisiones UX/UI
Las alternativas descartadas son las que el repo documenta o las que se deducen directamente de una restricción escrita. Cuando es una lectura mía, lo indico.
Hoy muestra una carta con el número de día, el enfoque, el ejercicio principal y la prescripción. El mes es un plan que se va marcando.
Quita la decisión diaria (principio 4) y convierte el progreso en algo visible, sin lista infinita.
Una biblioteca de rutinas para elegir. Es lo que hacen las apps genéricas y reintroduce la fatiga de decidir.
Semilla = UID + número de día. El mismo día da la misma sesión en cualquier dispositivo; cada usuario rota los ejercicios en su propio orden.
Confianza y testabilidad: el motor es puro y se prueba con vitest. Variedad con intención, no azar.
Generar al azar cada vez. Rompe la recuperación entre dispositivos y no se puede explicar «por qué hoy».
Cuenta atrás por serie, repeticiones marcadas por cadencia y cronómetro de descansos. Al final, una pregunta: qué tan duro fue.
Con las manos ocupadas no se pulsan botones (principio 3). El RPE final alimenta el ajuste del día siguiente.
Pedir confirmación serie a serie. Obliga a soltar la pesa y a tocar una pantalla pequeña en pleno esfuerzo.
Cuatro duraciones, máximo 25. Los ajustes antiguos de 35 o 45 minutos pasan automáticamente a 25.
Es una apuesta por la adherencia. Respaldo indirecto citado por el propio producto: un meta-análisis de fuerza en general asocia una serie por ejercicio, una a tres veces por semana, con ganancias de fuerza.
Sesiones de 35 a 45 minutos, que PRODUCT.md aún contemplaba. Se recortaron al afinar el motor.
«Día N» es el N-ésimo día del programa del usuario. Perder un día no salta bloques ni castiga.
Protege la motivación de quien falla un día y mantiene el orden fisiológico de los patrones de movimiento.
Un calendario rígido de lunes a domingo, que convertiría cada ausencia en un hueco en el plan.
Un toque, sin contraseñas; popup en escritorio y redirección en móvil o PWA cuando el popup falla.
Cero contraseñas que custodiar y fricción mínima. El historial viaja con la cuenta.
Email y contraseña, y acceso anónimo en producción. El repo los excluye de forma explícita.
Cada bloque puede mostrar su estudio, su diseño y un nivel de evidencia de A a D. Hay una página pública con una lista de lo que NO se promete.
La evidencia específica de pesa rusa es pequeña; decirlo genera más confianza que exagerar (principio 1).
Cifras de calorías exactas, «tonificar» o «mejor que correr». El propio sitio explica por qué no.
El botón de abandono llena una barra durante 1,6 s; si sueltas antes, vuelve en 200 ms. Con teclado basta Enter o Espacio.
Evita perder una sesión por un toque accidental con las manos sudadas. Lento mientras decides, rápido cuando el sistema responde.
Un diálogo «¿seguro?» con dos botones juntos, fácil de acertar sin querer (lectura mía a partir del comentario del código).
Se sustituyó un sistema con papel, grano, rayos y temática de lotería por grafito casi negro, blanco frío y una tinta eléctrica por enfoque.
DESIGN.md conserva la mecánica (una tinta por enfoque, una tarjeta por día, un mes que se marca) y «pierde la nostalgia». Mi lectura: un fondo oscuro y números grandes encajan mejor con garajes con poca luz.
El sistema anterior: papel crema, grano, frijoles, palabras de lotería. Hoy son reglas explícitas de «no hagas».
06 · Sistema visual
Grafito casi negro, blanco frío para el texto y una sola tinta eléctrica (la del enfoque del día) que pinta la tarjeta, el reproductor y los acentos.
Regla de la tinta: es el único color saturado de una pantalla; no se mezclan dos tintas en la misma superficie (el mes, con una barra por día, es la excepción informativa). Cada tinta trae su par --on-ink para que el texto encima sea legible: negro sobre potencia, blanco sobre fuerza.
| Enfoque | Tinta | Qué trabaja |
|---|---|---|
| Potencia | Bermellón | Balístico de cadera |
| Fuerza | Cobalto | Empujes, tirones, sentadillas, bisagras lentas |
| Resistencia | Jade | Series largas e intervalos |
| Híbrido | Caléndula | Complejos |
| Técnica | Rosa | Get-up y control |
| Recuperación | Aqua | Flujos suaves; mantiene la racha |
Peso muerto
Titulares, nombres, botones. Condensada, cursiva, mayúsculas.8 × 8 kg
Cuentas atrás, reps y kilos. El eje--heat engrosa y estrecha los números con el esfuerzo.Cadera atrás y espalda larga: la pesa se levanta sin queja ni carga.
16 px mínimo en lectura; nunca en cursiva.

<dialog> que entra y sale por el mismo borde; barra inferior de cuatro destinos con píldora de tinta tras el icono activo.Nota sobre las capturas. La app privada requiere cuenta de Google y yo no creé ninguna para este caso. Las pantallas internas (Hoy) son las capturas que el repo publica en su README; las públicas (landing, ciencia, FAQ) las hice yo sobre la web real, en móvil 390 px y en escritorio.
07 · Microinteracciones y estados
En los últimos tres segundos el número late (tick-pulse); al cambiar, hace un pequeño pop. El tamaño es fluido: entre 72 y 120 px según la altura de la pantalla, para leerlo desde lejos.
El eje --heat de la tipografía variable cambia peso y ancho: más esfuerzo, números más densos. La cuenta de trabajo usa el valor máximo; el descanso, uno bajo.
El relleno lineal de 1,6 s deja tiempo para arrepentirse. Si sueltas antes, vuelve en 200 ms: la respuesta del sistema es rápida y la decisión del usuario es lenta.
Pitidos (WebAudio), voz (SpeechSynthesis) y vibración, cada uno apagable. Los navegadores exigen un gesto previo, así que el audio se inicializa en el primer toque de Empezar.
Pantallas dedicadas para carga (Splash), carga lenta (SlowHint), error (LoadError) y navegadores integrados de apps (InAppBrowserNote), donde el acceso con Google puede fallar.
La sesión activa se guarda como borrador. Si cierras la app, vuelves donde la dejaste; el cierre final se escribe en un único writeBatch, que funciona offline.
Todo el movimiento respeta prefers-reduced-motion (referenciado en las hojas de estilo, la figura 3D y la celebración). La regla de diseño es explícita: nada de destellos rápidos.
08 · Confianza y copy
La ciencia no es un párrafo escondido: se muestra como etiqueta de nivel, cita corta y diseño del estudio. Y se acompaña de una lista de lo que no se promete.
El repo fija una voz «bro», directa y motivadora, con la ciencia como respaldo y no como sermón. La landing mantiene términos claros: «pesa rusa» como principal y «kettlebell» como sinónimo.
El texto público limita las promesas a lo que cita (por ejemplo, que correr exigió más oxígeno que 10 minutos de swings a igual esfuerzo percibido) y avisa de los casos donde no hay grupo de control.
09 · Accesibilidad y rendimiento
Una ejecución mía (Lighthouse 13.5.0, móvil, 23 de octubre de 2026, desde mi equipo) sobre la portada: accesibilidad 100, buenas prácticas 100, SEO 100 y rendimiento 63, con LCP de 7,5 s simulados, CLS 0 y TBT 0 ms.
Una sola medición con throttling simulado; no sustituye a datos de campo.Botones del reproductor de 44 px (h-11 w-11), números fluidos de hasta 120 px, aria-live asertivo solo en la cuenta atrás y apagado en el resto, aria-label y aria-pressed en los controles de salir y silenciar.
DESIGN.md indica que el gris de apoyo sobre night-2 alcanza 5,6:1, y define no depender solo del color ni del sonido para transmitir información.
No probé la app privada con lector de pantalla ni con un dispositivo real en un gimnasio. El rendimiento de la sesión (3D, audio, voz) está sin medir por mí.
10 · Stack y decisiones técnicas
| Tema | Decisión | Motivo |
|---|---|---|
| Framework | Next.js 16 (App Router), React 19, TypeScript, Tailwind 4 | Landing renderizable en servidor para SEO; app como PWA. |
| Backend | Firebase Auth + Cloud Firestore (SDK modular) | Sin servidor propio; caché offline persistente y cola de escrituras integradas. |
| Datos | Subárbol users/{uid}/… | Reglas de seguridad triviales (request.auth.uid == uid). |
| Offline | persistentLocalCache + service worker de caché mínima | El gimnasio tiene mala cobertura; la app debe abrir y registrar sin red. |
| Cierre de sesión | writeBatch atómico | Una transacción exige conexión; un batch no. |
| Motor | Funciones puras con tests en vitest | Determinista, probable y válido en cliente, servidor o sin red. |
| Personajes | Figuras 3D (three.js) con pipeline de Blender y validador de GLB | Mostrar la técnica de lado, de frente y en tres cuartos. |
| Modo demo | LocalRepository detrás de una variable de entorno | Previsualizar la UI sin Firebase; nunca en producción. |
El acceso a datos va detrás de una interfaz Repository con dos implementaciones (Firestore y localStorage), lo que permite diseñar y probar la UI sin backend.
11 · Aprendizajes y próximos pasos
Pruébala
La landing, la ciencia y las guías son públicas. Para entrar a la app hace falta una cuenta de Google.