DesarrolloUX

El blog, por dentro

Qué cambió en el diseño del blog y cómo aproveché el proceso para integrar en el sistema los componentes que habían quedado fuera.

Introducción

En 2024 dejé de escribir en el blog. No porque me hubiera quedado sin ideas, sino porque había empezado a trabajar en la documentación de Runware y se llevó todo el tiempo que tenía disponible. Este sitio quedó aparcado y, casi sin darme cuenta, pasaron un par de años.

Cuando volvieron las ganas de experimentar y de escribir por mi cuenta, retomé el proyecto para poner en marcha el Lab, una nueva sección donde publicar pequeños experimentos. Una cosa llevó a la otra y acabé rediseñando el blog entero.

El diseño anterior funcionaba, pero durante esos dos años había aprendido mucho y quería aprovecharlo para mejorar la web. Había componentes que todavía no utilizaban el sistema y demasiados valores elegidos a ojo. El objetivo no era solo cambiar el aspecto, sino terminar con un sistema más coherente y más fácil de modificar.

En este artículo vamos a desmontarlo. Primero veremos qué ha cambiado por fuera. Después entraremos en el sistema de temas y en el trabajo de color que exigió sustituir el violeta por cian y ámbar.

La dirección visual

Buscaba una estética más fría y contenida, con un fondo muy oscuro y unos pocos indicadores de color. Durante el proceso volvía una y otra vez al interior de la nave de Interstellar. Es mi película favorita, así que tampoco voy a fingir demasiada objetividad. No quería copiarla ni llenar la web de naves espaciales, solo recuperar esa sensación de máquina construida para trabajar.

De ahí salieron los dos acentos del blog. El cian acompaña todo lo que se lee o se puede pulsar. Es el color que marca el camino. El ámbar queda reservado para momentos puntuales, donde puede llamar la atención sin competir con el contenido.

La página de inicio es donde más se nota el cambio. La versión anterior era amable y colorida, con palabras destacadas en varios tonos y formas flotando alrededor de la fotografía. Los artículos se distribuían en tarjetas. La nueva es más contenida. El contenido vuelve a ser el protagonista y los artículos forman una única lista cronológica.

Un reloj que no sirve para nada

En una esquina de la portada hay un pequeño reloj de misión. Muestra T+…s, los segundos transcurridos desde el 1 de enero de 1999, más o menos cuando empecé a programar. No recuerdo la fecha exacta, así que Año Nuevo tendrá que valer.

No tiene ninguna utilidad práctica. Es completamente innecesario, y precisamente por eso funciona. Antes de leer una sola línea ya te ha contado en qué clase de sitio estás.

tiempo de misiónT+s

La lección del color

El blog ya utilizaba OKLCH, así que no tuve que cambiar de espacio de color. OKLCH describe cada color mediante tres valores: luminosidad, croma y tono. Su principal ventaja es que la luminosidad se aproxima mucho mejor a cómo percibimos el brillo que en otros formatos habituales. Esto hace que ajustar contraste o construir escalas resulte bastante más predecible.

Durante años apliqué una regla que parecía lógica: si todos los acentos comparten luminosidad y croma, y solo cambia el tono, entonces todos parecerán parte de la misma familia.

La primera mitad era cierta. La segunda era el problema.

Todos iguales, todos planos

Los tonos no disponen del mismo margen de croma. La cantidad de saturación que podemos pedir antes de salir de la gama reproducible depende tanto del tono como de la luminosidad. Si obligamos a todos a compartir el mismo valor, la paleta completa queda limitada por el color con menos margen.

El violeta aparece en esta comparación porque era el acento principal del diseño anterior. Tiene bastante margen y por eso mi regla de mantener el mismo croma nunca dio demasiados problemas. Al sustituirlo por cian y ámbar terminé entrando en una zona mucho más estrecha.

La gráfica comprueba cuál es el croma máximo que puede tener cada tono antes de que el navegador tenga que recortarlo para representarlo en sRGB. Utilizo sRGB porque es la gama de color común que puedo dar por segura en una web. Con una luminosidad de 0.70, estos son los valores aproximados para los tonos que nos interesan:

TonoCroma máx. aprox.Margen relativo
Violeta · 295°~0.18Amplio
Ámbar · 79°~0.15Intermedio
Cian · 200°~0.12Estrecho

No son límites universales: cambian al mover la luminosidad y también dependen de la gama de color con la que trabajemos. Lo importante es la diferencia entre ellos. Pedir el mismo croma no garantiza obtener colores igual de vivos.

Puedes comprobarlo en el siguiente ejemplo. Mantén la luminosidad en 0.70, salta al cian y sube el croma por encima de 0.12: el valor solicitado supera lo que sRGB puede representar y el indicador lo marca como recortado. En el violeta todavía queda margen. La gráfica inferior dibuja ese techo para todos los tonos y permite ver que no forma una línea recta.

croma solicitado0.100

máximo que admite este tono0.100

200
0.7
0.1
ir a
el máximo de croma que cada tono puede sostener a esta luminosidad. mucho más en el violeta que en el cian

La solución no consiste en llevar cada color hasta el límite, sino en ajustar su croma por separado. Los acentos pueden compartir una luminosidad que los relacione entre sí, mientras cada tono utiliza la intensidad que necesita y realmente puede reproducir.

En esta paleta el ámbar tiene algo más de croma que el cian. También aparece con mucha menos frecuencia, de modo que puede ser más intenso sin apoderarse de la interfaz. El cian guía. El ámbar interrumpe cuando hay un motivo.

El problema del ámbar

En el tema claro aparece otro problema. El ámbar está muy cerca del amarillo, y el amarillo necesita bastante luminosidad para conservar su carácter. Si lo oscurecemos demasiado para ganar contraste sobre blanco, termina convertido en un oliva apagado.

Podría desplazar el tono hacia el naranja, pero entonces la misma señal usaría dos colores distintos según el tema. Preferí mantener el tono y cambiar el papel que cumple. En oscuro puede comportarse como una pequeña luz. Sobre papel lo utilizo con más contención, como una marca de tinta.

Tema oscurooklch(70% 0.14 79)

El ámbar puede comportarse como una luz.

El mismo color sobre blancooklch(70% 0.14 79)

Conserva el ámbar, pero pierde demasiado contraste.

Tema clarooklch(63% 0.132 79)

Baja lo justo para ganar contraste sin dejar de parecer ámbar.

De la paleta al sistema

Elegir cuatro colores agradables no basta para construir un diseño. Lo interesante empieza cuando definimos qué responsabilidad tiene cada uno, cómo se relaciona con el resto y qué debe ocurrir al cambiar de tema.

El casco

El fondo oscuro es un azul petróleo casi negro. Tiene suficiente color para no parecer gris, pero no tanto como para competir con el campo de estrellas y las órbitas de la portada. Los paneles y bordes permanecen dentro de esa misma familia en lugar de introducir nuevos tonos. El texto utiliza un blanco roto para evitar el contraste agresivo del blanco puro.

Casco · fondooklch(19% 0.021 226)
Cian · caminooklch(70% 0.108 200)
Ámbar · señaloklch(70% 0.14 79)
Texto · blanco rotooklch(79% 0.01 85)
El contraste siempre es relativo

Al oscurecer el fondo desapareció una capa entera de bordes tenues. Sus valores se habían elegido para quedar ligeramente por debajo del fondo anterior. Frente al nuevo casco eran más oscuros que la propia página y, por tanto, casi invisibles. Hubo que elevarlos para que volvieran a distinguirse. Cuando cambia el suelo, cambia la relación de todo lo que se apoya en él.

Dos temas, no tres paletas

El blog ya tenía un tema claro y otro oscuro. El problema era que mantenía tres versiones de la paleta: una para el modo claro, otra para el oscuro y una tercera para el modo por defecto cuando el sistema operativo prefería oscuro. default no era un tercer tema, pero en el CSS se comportaba como otra copia que había que mantener sincronizada.

Ahora cada color se define una sola vez con sus dos valores dentro de light-dark(). La propiedad color-scheme decide cuál utilizar. Si no eliges un tema, el navegador sigue la preferencia del sistema operativo. Si utilizas el selector del blog, color-scheme queda fijado en claro u oscuro.

El modo por defecto deja de necesitar su propia paleta
/* Antes */
[data-theme="light"] { --color-text: oklch(44% 0.01 285deg); }
[data-theme="dark"] { --color-text: oklch(79% 0.01 85deg); }

@media (prefers-color-scheme: dark) {
  [data-theme="default"] { --color-text: oklch(79% 0.01 85deg); }
}

/* Ahora */
:root {
  color-scheme: light dark;
  --color-text: light-dark(oklch(44% 0.01 285deg), oklch(79% 0.01 85deg));
}

[data-theme="light"] { color-scheme: light; }
[data-theme="dark"] { color-scheme: dark; }
css

Para modificar un color edito una línea y veo sus dos versiones juntas. El modo por defecto continúa funcionando, pero ya no contiene una paleta propia. Solo quedan duplicadas unas pocas variables que no son colores, porque light-dark() no puede utilizarlas. La mayor parte del tercer bloque ha desaparecido.

Una escala de intensidad

El texto y los elementos de la interfaz utilizan la misma escala conceptual: prominent, strong, regular, quiet y subtle. Hay una versión para texto y otra para líneas y superficies, pero ambas responden a la misma pregunta: ¿cuánto peso visual necesita esta pieza?

Superficie · element-*

Texto · text-*

prominentstrongregularquietsubtle

Los pasos no son cinco colores escogidos a mano. Parten de un ancla y se obtienen cambiando su luminosidad. En el tema claro, aumentar la intensidad implica oscurecer. En el oscuro ocurre lo contrario. La escala conserva el significado aunque la operación se invierta.

Antes había nombres como hover o selected. Parecían descriptivos hasta que el mismo valor resultaba útil en un elemento que no estaba seleccionado ni bajo el puntero. Nombrar por intensidad evita esa mentira: un color no sabe para qué componente se utiliza, solo cuánto debe destacar.

Los colores semánticos (success, warning, error, info y note) quedan fuera de esta escala. No representan niveles de intensidad, sino significados distintos con el mismo rango jerárquico.

Significado no es jerarquía

Los colores semánticos comparten el mismo tratamiento para que ninguno domine por defecto. El verde no debe parecer más importante que el rojo ni una nota más urgente que un aviso. La jerarquía la decide el contenido. El color se limita a explicar qué clase de mensaje estamos viendo.

Un token es una decisión

El blog ya tenía tokens, escalas y una base de color en OKLCH. El problema era que no todo utilizaba ese sistema. Algunos componentes habían resuelto sus necesidades por separado y se quedaron fuera.

Los controles de formulario eran el ejemplo más claro. Cada uno había terminado con su propio espaciado, borde, estado de hover y anillo de foco. Ninguno era desastroso por sí solo, pero construir el siguiente control obligaba a elegir entre varios valores casi iguales sin saber cuál representaba la decisión correcta.

40

Ahora todos comparten la misma geometría y los mismos estados. Esto no solo hace que se parezcan: permite cambiar una decisión desde el lugar donde esa decisión vive.

Esa es la diferencia importante. Un token no es un valor compartido, sino una decisión compartida. Dos elementos pueden tener hoy el mismo radio o el mismo espacio por casualidad. Solo deberían utilizar el mismo token si, al cambiar uno mañana, también querríamos cambiar el otro.

Una paleta reúne valores. Un sistema reúne relaciones y decisiones. El rediseño no solo cambió el aspecto del blog. También redujo el número de lugares que tengo que tocar para modificarlo y, en la mayoría de los casos, ese número ahora es uno.

Menos superficie, más claridad

Al llevar el sistema a los artículos apliqué una regla sencilla: si un elemento ya se distingue por su fondo, no necesita además un borde que repita la misma separación.

Los bloques de código utilizan una superficie rellena, con el título presentado como un comentario //, y prescinden del marco. Los avisos siguen el mismo criterio: el color de fondo y la etiqueta ya explican dónde empiezan, dónde terminan y qué significan.

En modo oscuro el fondo del código es algo más claro que la página. Quería que se leyera como un panel iluminado sobre el casco, no como un agujero todavía más oscuro. Es contenido importante, así que conviene darle más presencia que al fondo de la página.

El código también separa los colores de marca de los que comunican un significado. Una línea destacada utiliza el azul semántico y las diferencias utilizan verde o rojo. El cian queda reservado para la lectura y la navegación. Así cada color conserva una función reconocible en lugar de convertirse en una decoración disponible para cualquier cosa.

Los detalles también cuentan

El sistema marca la dirección, pero son los detalles pequeños los que terminan de darle carácter.

Al pasar por un enlace, un punto de luz recorre el subrayado como un pequeño cometa. Los encabezados muestran en el margen su profundidad de Markdown (##, ###) y las separaciones horizontales se convierten en //. Las listas ordenadas utilizan números monoespaciados. En las listas sin ordenar, el marcador se estira ligeramente al pasar por cada elemento.

El título de cada página tampoco aparece de golpe. Sus letras pasan por una breve secuencia de glifos antes de asentarse en el texto definitivo. Para evitar que la animación salte dos veces, espera a que la fuente esté disponible antes de empezar, con un límite de tiempo por si la carga se retrasa.

El blog, por dentro

Ninguno de estos detalles es imprescindible. Juntos, sin embargo, hacen que el blog se comporte como el mismo objeto en todas partes. Las animaciones más visibles respetan prefers-reduced-motion, porque una identidad visual no debería imponerse a costa de la comodidad de quien la visita.

Un sitio para experimentar

La incorporación más reciente es el Lab, un espacio para pequeños experimentos. Comparte el mismo sistema visual que el resto del blog, pero cambia la actividad principal: allí no se entra solo a leer, sino también a probar cosas.

Ahora mismo buena parte de los experimentos gira alrededor de lo que pueden y no pueden hacer los modelos de IA. No quiero convertirlo en una sección exclusiva sobre inteligencia artificial. Su función es precisamente dejar sitio para construir algo por curiosidad y aprender lo suficiente como para poder explicarlo.

Los experimentos tampoco terminan en una demostración aislada. Publico el código y acompaño cada proyecto con un artículo que desmonta su funcionamiento. De esta forma el Lab alimenta el blog, y el blog convierte las pruebas en algo que otra persona puede entender y reutilizar.

Conclusión

La parte más visible de este trabajo es la nueva estética: el casco oscuro, el cian, el ámbar y todos los pequeños gestos de cabina. Pero el cambio importante está debajo. Ahora los temas comparten definiciones, las escalas expresan intensidad, los controles parten de la misma geometría y cada token representa una decisión que merece cambiar en conjunto.

También hay algo que no cambió: la tipografía. Sigue siendo redonda y cercana frente a toda esa instrumentación fría. Me gusta ese contraste porque resume bien lo que intento hacer aquí: explicar cómo funcionan las cosas sin dejar de sonar como una persona.

Una voz cálida dentro de una máquina fría.

Puedes apoyarme para que pueda dedicar aún más tiempo a escribir artículos y tener recursos para crear nuevos proyectos. ¡Gracias!

Contribuir