---
title: El blog, por dentro
description: 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.
url: https://www.felixsanz.dev/es/articulos/el-blog-por-dentro
language: es
published: 2026-07-28
updated: 2026-08-08
tags:
  - development
  - ux
alternate-en: https://www.felixsanz.dev/articles/the-blog-taken-apart
---

# El blog, por dentro

## 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.

![La página de inicio de 2024: palabras clave de varios colores, formas geométricas flotando alrededor de una foto, y los artículos mostrados en una cuadrícula de tarjetas.](https://www.felixsanz.dev/assets/home-before.BMNi--O9_Z1OyBDh.jpg)

*La antigua página de inicio*

![La nueva página de inicio: un diseño de cabina oscuro con el eslogan, un avatar cósmico, un reloj de misión, y todos los artículos en una única lista cronológica.](https://www.felixsanz.dev/assets/home-after.BYBbWqWc_Z1rqsGx.jpg)

*La nueva página de inicio*

### 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.

*[Mission clock]*

## 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:

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

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.

*[Interactive: OKLCH gamut explorer]*

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.

79°

**Tema oscuro**`oklch(70% 0.14 79)`

El ámbar puede comportarse como una luz.

79°

**El mismo color sobre blanco**`oklch(70% 0.14 79)`

Conserva el ámbar, pero pierde demasiado contraste.

79°

**Tema claro**`oklch(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.

*[Color palette]*

> [!WARNING]
> **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.

```css
/* 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; }
```

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.

> [!NOTE]
> **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.

Campo

Selector

Opción AOpción B

Rango40

UnoDos

RadioOpción

CasillaInterruptorBotón

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](https://www.felixsanz.dev/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.**
