La mayoría de diseñadores optimizan pantallas. Yo optimizo el sistema que hay detrás.
La diferencia no es filosófica — es estructural. Y se hace evidente en el momento en que algo se rompe.
Qué es una pantalla y qué no es
Una pantalla es un snapshot. Un estado, un contexto, un momento. Muestra el happy path en el viewport ideal con la longitud de contenido correcta y un usuario que sabe exactamente lo que está haciendo.
Un sistema es el conjunto de reglas que genera cada snapshot. Gestiona los edge cases, los estados de error, los estados vacíos, el contenido que es el doble de largo de lo que el diseñador esperaba, el usuario que está en un Android de cuatro años con el 20% de batería y una conexión lenta.
Diseñar una pantalla es fácil. Diseñar las reglas que hacen que cada pantalla sea correcta bajo cualquier condición — ese es el problema real.
Las preguntas que preceden a cualquier diseño
Cuando empiezo un proyecto, no abro una herramienta de diseño primero. Hago cuatro preguntas:
¿Cuántos estados tiene este componente? Default, hover, active, disabled, loading, error, empty, skeleton. Un botón sin todos sus estados no es un botón — es un rendering optimista de uno. Los estados que saltas en diseño son los que se rompen en producción.
¿Cómo escala? A otras marcas, otros idiomas, otros viewports, otros contextos para los que aún no te han pedido diseñar. Un componente que solo funciona para el caso de uso que te han dado no es un componente — es un one-off.
¿Qué se rompe en los extremos? El diseño interesante ocurre cuando el contenido es tres veces más largo de lo esperado, cuando la red falla a mitad de una acción, cuando el usuario es interrumpido y vuelve a un estado desconocido. Diseña la excepción, no solo la regla.
¿Quién toca esto después de mí? Un sistema que solo funciona cuando estás ahí para explicarlo no es un sistema — es una dependencia. El test: ¿puede un ingeniero implementarlo sin una llamada?
El background de ingeniería
Tres años escribiendo C#/.NET y MongoDB antes de moverme a diseño cambiaron cómo pienso sobre las interfaces.
El código es honesto sobre las restricciones. No puedes fingir que algo funciona — o compila o no, o la query devuelve los datos correctos o no. La brecha entre "parece correcto" y "es correcto" no existe en una base de código. Sí existe en un mockup.
El diseño tiene una tendencia peligrosa hacia el optimismo. Mostrar estados ideales en condiciones ideales a stakeholders que no saben lo que no están viendo.
El background de ingeniería es una calibración permanente contra ese optimismo. Cada decisión que tomo en diseño pregunta: ¿qué pasa cuando esto falla? No como hábito pesimista — como requisito estructural.
Un ejemplo real: 15 marcas, un sistema
En Vocento — mayor grupo mediático de España — el reto no era diseñar un producto. Era diseñar un sistema sobre el que 15 productos pudieran correr sin romperse.
Cada marca tiene su propio contexto editorial, su propio modelo de suscripción, su propia densidad de contenido, su propia audiencia. Pero todas comparten la misma infraestructura de base.
La restricción era que cualquier decisión de diseño tomada para una marca tenía que funcionar para las quince. Eso elimina una clase de decisiones inmediatamente — cualquier cosa que dependa de una longitud de contenido específica, una voz de marca específica, un precio específico.
Lo que queda después de ese filtro son decisiones estructuralmente correctas. Esas son las que vale la pena tomar.
El resultado fue un sistema de diseño con una arquitectura de componentes única que cada marca instancia de forma diferente — no mediante overrides y excepciones, sino mediante un sistema de tokens que separa lo que cambia (identidad de marca) de lo que no cambia (comportamiento de interacción).
Reducción del 40% en el tiempo de handoff diseño-desarrollo. No porque nos moviéramos más rápido — porque el sistema tenía menos preguntas que necesitaban respuesta.
Qué aspecto tiene esto en código
Un sistema no es una abstracción. Es un conjunto de decisiones concretas codificadas de forma que la elección incorrecta sea más difícil que la correcta.
// A component without system thinking
function Card({ title, description, image, cta }) {
return (
<div className="card">
<img src={image} />
<h2>{title}</h2>
<p>{description}</p>
<button>{cta}</button>
</div>
);
}
// The same component with system thinking
interface CardProps {
title: string;
description?: string;
image?: { src: string; alt: string };
cta: {
label: string;
href: string;
variant: 'primary' | 'secondary';
};
state?: 'default' | 'loading' | 'error';
}
function Card({ title, description, image, cta, state = 'default' }: CardProps) {
if (state === 'loading') return <CardSkeleton />;
if (state === 'error') return <CardError />;
return (
<article className="card">
{image && (
<figure className="card__image">
<img src={image.src} alt={image.alt} loading="lazy" />
</figure>
)}
<div className="card__body">
<h2 className="card__title">{title}</h2>
{description && (
<p className="card__description">{description}</p>
)}
</div>
<footer className="card__footer">
<a href={cta.href} className={`btn btn--${cta.variant}`}>
{cta.label}
</a>
</footer>
</article>
);
}
La diferencia no es complejidad — es explicitud. Cada edge case es una decisión, no un accidente.
El checklist práctico
Antes de diseñar cualquier componente:
- Lista todos los estados: default, hover, active, disabled, loading, error, empty, skeleton
- Define qué pasa con contenido 3× más largo de lo esperado
- Define qué pasa cuando falta el contenido completamente
- Define el comportamiento en móvil — no como afterthought
- Nombra el componente como si no fueras a estar ahí para explicarlo
- Escribe la spec del componente antes de abrir cualquier herramienta
No pantallas. Sistemas. Las pantallas son una consecuencia de tener el sistema correcto.