Foundation
8 de junio, 2026 · revisión 1
Todo sitio es una declaración sobre lo que su autor cree que importa. Este es el mío y la declaración está en el medio antes que en el texto: es un plano. No la metáfora decorativa de un plano, el sitio se comporta como uno. Líneas finas, retícula al fondo, una sola tinta azul, y nada que se mueva sin que lo muevas.
Este es el primer texto, y es también el plano del plano: cómo está construido y sobre todo, por qué de cada decisión. Voy a usar cada pieza del sistema mientras la explico. Este post se explica a sí mismo.
Un plano que necesita ejecutarse para mostrarse ya no es un plano: es una promesa.
El sitio no ejecuta nada
La regla más dura del proyecto es la más simple de verificar: en todo lo que se
publica no hay una sola etiqueta <script>. Cero JavaScript en tu navegador.
Nada de frameworks, nada de hidratación, nada de analítica que te siga.
No es una optimización tardía, es la decisión de la que cuelgan todas las demás. Si una funcionalidad parece necesitar JavaScript, la respuesta es: no se hace, o se resuelve cuando construyo el sitio, o se resuelve con CSS moderno. El sitio se genera entero como HTML estático con Astro y se sirve desde el borde. El código actual es el resultado, no la maquinaria.
El color lo decide tu sistema
No hay botón de modo claro/oscuro. No porque me diera pereza, sino porque el
interruptor correcto ya lo tienes en tu sistema operativo, y duplicarlo significa
JavaScript, localStorage y un parpadeo al cargar. El sitio respeta lo que tu
sistema declara, y nada más:
:root {
color-scheme: light dark;
--paper: light-dark(#f5f2ea, #0e1b3d); /* paper / Prussian blue */
--ink: light-dark(#22252b, #dce4f5); /* ink / light line */
--blue: light-dark(#2433d0, #9db6ff); /* the only accent */
}light-dark() resuelve cada color según prefers-color-scheme. De día el plano
es papel cálido con tinta ultramar. De noche es un cianotipo: líneas claras sobre
azul de Prusia. No son dos temas: es el mismo plano con dos revelados.
Las letras de la portada no son aleatorias
Cada texto tiene una portada con tres letras enormes en contorno, que se dibujan solas. No salen de un hash ni de un generador, son, literalmente, las primeras tres letras del título. Determinista, aburrido a propósito, siempre el mismo resultado para el mismo título:
export function heroLetters(title) {
return title
.normalize('NFD')
.replace(/[̀-ͯ]/g, '') // strip diacritics
.replace(/[^a-zA-Z]/g, '') // letters only
.slice(0, 3); // "Foundation" → "Fou"
}El trazo que ves dibujarse es CSS puro: un stroke-dashoffset animado sobre un
SVG en línea. Si tu navegador no soporta la animación, las letras simplemente
aparecen ya trazadas. Nunca invisibles, nunca rotas.
Detalle AAquí iría un Lorem Ipsum
Las fotos de este sitio duermen en un duotono azul y se revelan a color cuando cruzan el centro de la pantalla. Llegar ahí costó dos versiones, y las guardo porque el mapa de lo que descarté explica el criterio mejor que la solución que sobrevivió.
La primera teñía la imagen con filter: hue-rotate. Se veía bien en los
extremos, pero los estados intermedios pasaban por verdes turbios: el tono
cruzaba medio círculo cromático para llegar al azul. La reemplacé por una
capa mix-blend-mode: color cuya opacidad se anima; el azul se levanta limpio,
sin pasar por el fango.
El segundo intento fue más caro. Usé overflow: hidden en el contenedor de la
imagen. hidden convierte al elemento en scroll container, y eso congela el
reloj de animation-timeline: view(), la animación dejaba de avanzar y la imagen
se quedaba siempre limpia. La cura es una sola línea: overflow: clip.
Recorta igual, pero no crea scroll container.
Acá está el resultado, vivo. Haz scroll lento sobre la imagen: transición en azul
hasta que su recorrido cruza el centro, ahí se limpia de golpe, y vuelve a
velarse al salir. Todo conducido por animation-timeline: view(), cero JS. Si pasas el mouse por encima y se limpia al instante.

La columna de lectura mide 36rem, pero una figura puede romperla cuando lo
amerita, un diagrama, una captura densa. Basta con marcarla:

Todo se cocina antes de llegar a tu navegador
Escribo en Markdown. Lo demás pasa cuando construyo el sitio, una sola vez, para que no haga costo en navegador, rapidez. Cada bloque de este texto recorrió esta tubería:
Ese diagrama es Mermaid. Lo escribí como texto y se dibujó como SVG en el build,
en sus dos variantes de color. El coloreado de este mismo bloque de código lo
hace Shiki, también al construir. Las figuras se arman de un pequeño plugin propio a partir de un 
normal. Tu navegador recibe SVG y HTML, la librería de Mermaid y el resaltador nunca
viajan a tu navegador.
Hasta las tipografías Oswald para los rótulos, Gothic A1 para el cuerpo viven en mi dominio. En producción no sale una sola petición a un CDN de fuentes.
El número es para siempre
Arriba de cada título hay un número: este es el Nº 777. No se calcula del orden
cronológico. Lo escribo a mano en el texto y no cambia nunca. Si borrara un texto
o publicara uno con fecha vieja, los números no se corren: un plano que cambia de
número es un plano corrupto. Si dos textos comparten número, el build falla antes
de publicar. La numeración es manual, única e inmutable, a propósito.
Cimiento
Eso es la fundación: un puñado de decisiones, y al lado de cada una su opción iterada con la causa de descarte anotada. Por eso este post guarda las dos cosas a la vista.
El resto son textos. Este era el plano.