Guía de estilo

Última actualización

Guía de estilo 1.0

El sistema detrás de aitormurillo.com. Cada valor sale del código a 1 de octubre de 2026 (frontend/, Nuxt 4 + Tailwind v4).

Para diseñadores y desarrolladores front-end. Cada regla da primero el valor de diseño y, cuando existe, el token, la utilidad o el componente Vue que lo implementa, en Mute.

Principios

Un tamaño, un peso.

La jerarquía sale de la posición en la retícula, las mayúsculas y el color, nunca de la escala.

El texto es la interfaz.

Cada control es una palabra: sin botones con relleno o borde, sin iconos. Los únicos signos son + (girado 45° para Cerrar), ×, ↗, ↑, ⌘K.

Claro, con el color de los proyectos.

Fondo blanco, texto negro, un gris, un azul y un gris de filete. El resto del color viene de las imágenes de los proyectos.

Todo empieza en el borde de una columna.

Los cinco bloques de la cabecera son las columnas maestras de toda la web.

El movimiento tiene dos curvas.

Reveal, para máscaras y diapositivas; settle, para entradas y zoom.

El hover es una mejora.

Los efectos de hover solo existen en dispositivos que pueden hacer hover; el foco del teclado los replica donde aportan significado.

Tipografía

Aitor Murillo

Geist Mono Regular, 12/16, en todas partes. La jerarquía sale de la posición, las mayúsculas y el color.

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789 àáçèéíïòóúüñ ·,.:;!?¿¡()“”‘’
Ŀŀ ı Œœ € ™ + × ↗ ↑ ← → ⌘K

Texto corrido · CommonTextContent

Cada control es una palabra. Los párrafos están a 16px y la medida es de cuatro columnas, unos 45–60 caracteres.

  • Las listas usan un disco,
  • con una sangría de 2ch.

Los enlaces en el texto están siempre subrayados, porque el azul solo se parece demasiado al negro.

Familia

Geist Mono, regular, alojada en la web y reducida (latín, Latin-1, Ŀŀ ıŒœ €™ y flechas)

--font-primary · /fonts/GeistMono-Regular.woff2, preload, font-display: swap

Tamaño / interlineado

12px / 16px, en todas partes

--text-base / --text-base--line-height

Peso / espaciado

400 / 0

Corte de línea

text-wrap: pretty en todo

body

Alternativa

ui-monospace, monospace (también cubre los signos fuera del subset, como el japonés)

--font-primary

MAYÚSCULAS

El logo, los nombres de proyecto (siempre: lista, tarjetas, pie, título del proyecto en móvil), los códigos de idioma y la página de error.

Tipo frase

Todo lo demás: textos de la cabecera, cuerpo, etiquetas, créditos y controles.

Saltos de línea

Se respetan donde el campo del CMS los permite: lema, dirección y stack.

whitespace-pre-line

Recorte

UNA SOLA LÍNEA Y PUNTOS SUSPENSIVOS EN LA LISTA

Nombres y créditos de las filas de la lista en escritorio, y nombres de las tarjetas. El crédito que aparece al pasar sobre una tarjeta se muestra entero.

Color

Fondo
#FFFFFF
--color-white
Sobre negro 21:1

Tinta
#000000
--color-black
Sobre blanco 21:1

Mute
#767676
--color-gray
4,54:1 sobre blanco, 4,6:1 sobre negro (AA)

Enlace / activo
#0000EE
--color-blue
9,4:1 sobre blanco, 2,2:1 sobre negro: nunca texto sobre negro

Filete
#E6E6E6
--color-gray-light
Líneas y fondos de imagen, nunca texto

Activo

Sobre mí

Azul: la página actual en el menú principal, el idioma activo y la palabra activa del cambio de vista del Archivo. En la home el idioma activo se queda en blanco.

Inactivo

ES

Mute: idiomas inactivos, la palabra de vista inactiva y el resto de páginas en el menú móvil. Nunca se usa opacidad para los estados inactivos.

Inactivo → hover

Pasa al color del texto que lo rodea: negro sobre blanco, blanco en la home. Los botones de texto pasan de Mute a negro.

Hover de enlace

Negro → azul, 150ms por defecto o 200ms donde se indica.

Atenuado

Contexto

Opacidad 0,2, solo para mandar el contexto al fondo: las filas de la lista que no están en hover, y la página del proyecto y el bloque 2 de la cabecera detrás de Más proyectos.

Imagen ausente

Un bloque negro. Todo marco de imagen tiene fondo negro.

Selección

Seleccionado

Fondo azul, texto blanco.

Fondos

Home: negro. El resto de páginas: blanco. El fondo cambia de color durante la transición de página, nunca de golpe.

Sobre imagen

Solo en la home. Degradado superior de 180px, rgba(0,0,0,.32) → transparente. Degradado inferior de 200px, transparente → rgba(0,0,0,.36). Las etiquetas sobre imagen del resto de la web usan un bloque blanco tras el texto negro, nunca un velo.

Retícula, espaciado y maquetación

12 columnas en escritorio y 6 por debajo de 768px (el md de Tailwind). Margen lateral de 20px y medianil de 10px en todos los tamaños. Las maquetaciones anidadas reutilizan las pistas del padre con grid-cols-subgrid, así que una columna anidada siempre cae sobre una columna de la página.

container + main-grid · main-gap

1
2
3
4
5
6
7
8
9
10
11
12

1 · Logo
1–2

2 · Texto de cada página
3–6, el único bloque que cambia

3 · Menú principal
7–8

4 · Menú secundario, idiomas
9–10

5 · Reloj
11–12, a la derecha

Espaciado, en múltiplos de la unidad de 4px

4

Relleno horizontal de una etiqueta blanca sobre imagen

px-1

8

Relleno vertical de las filas de tablas y listas

py-2

10

Medianil; margen de la etiqueta en las tarjetas; separación de la galería; relleno superior de las filas en móvil

2.5

16

Separación entre párrafos y entre filas del banner

4

20

Margen lateral; relleno y separación entre filas de la cabecera; distancia de los elementos fijos al borde

5

24

Separación entre grupos en la columna de texto del proyecto

6

32

Separación entre filas del footer en móvil

8

40

Separación entre grupos del menú móvil; del texto del proyecto a su URL

10

48

Separación entre secciones en móvil (Sobre mí); del título al texto en legales y proyecto

12

96

Separación entre secciones en escritorio (Sobre mí); entre filas del footer en escritorio

24

120

Espacio bajo el contenido antes del footer

pb-30

Dónde empieza el contenido (todas las páginas menos la home)

Escritorio

32vh

Móvil

172px (la cabecera de dos filas del Archivo + 48px)

--page-content-top. pt-page-content resta la --header-height medida. La columna fija del proyecto en escritorio usa --page-content-top directamente. Esta página empieza a 32vh.

Capas

50

Banner de cookies

10

Cabecera; botón y carrusel de Más proyectos; pie de la home

5

Degradados de la home

3

Fila de la lista en hover, sobre la vista previa

2

Capa de la vista previa de la lista; diapositiva actual de la home

1

Diapositiva anterior de la home durante la cortina; la vista previa mostrada

Componentes

Enlace de texto

ArchivoSobre mí

Negro → azul en hover. Página actual en azul. Los enlaces externos se abren en otra pestaña; en los menús del footer llevan ↗ a la derecha.

CommonLink · CommonHeaderNavLink

Enlace en el texto

Azul y siempre subrayado en el texto corrido. Los enlaces azules sueltos (la URL del proyecto, “Ver programa ↗”) solo se subrayan en hover.

CommonContentLink

Enlace suelto

Subrayado solo en hover.

Botón de texto

Mute → negro en hover, 200ms. La palabra de vista inactiva, “× Borrar” y “Borrar búsqueda”.

CommonTextButton

Cerrar

+ girado 45° y “Cerrar”. Negro, azul en hover. Proyecto, menú móvil, Más proyectos y ajustes de cookies.

CommonCloseLabel

Selector de idioma

En mayúsculas, separados por un espacio. Activo en azul (blanco en la home), inactivo en Mute, en hover pasa al color que lo rodea. Cada enlace lleva lang y hreflang.

I18nSwitcher

Créditos

Diseño de Aitor Murillo / con Studio Norte

En la página del proyecto, “en colaboración con Y” va en su propia línea. Los colaboradores con web enlazan a ella (Mute → azul, en otra pestaña). Las categorías se leen “Tipo, Sector”. Los campos vacíos se omiten, nunca se sustituyen por un guion.

ProjectCollaborators

Fila de tabla

Filete de 1px arriba y 8px de relleno vertical. Sobre mí (servicios, colaboradores, docencia) y los menús del footer. Cada fila de esta página es una.

Controles del Archivo, filas de la lista y tarjetas · interactivo. Pasa sobre una fila o una tarjeta y prueba la búsqueda (⌘K).

Aitor Murillo
+ Menú

Archivo completo, 8 proyectos.

Cambiar vista de cuadrícula a

  • Archivo
  • Sobre mí
Contactoenesca

Controles del Archivo

El recuento se anuncia con aria-live. Cambio de vista: la vista actual en azul y la otra como botón de texto; por defecto, cuadrícula. Búsqueda: sin borde, máximo 320px, cursor azul, sin contorno de foco; la pista ⌘K pasa a Esc con el foco, y a × Borrar cuando hay texto. En vivo, sin distinguir acentos, todas las palabras deben coincidir, en nombre, año, diseño, colaboración, tipo y sector. La búsqueda y la vista duran toda la visita y no van en la URL.

ArchiveControls

Fila de la lista

Año 1–2 · NOMBRE 3–6 · Diseño 7–9 · Tipo, Sector 10–12. Móvil: año en la columna 1 y el resto apilado en 2–6, con 10px de relleno arriba y 12px abajo. En hover o con el foco, el resto de filas se atenúan a 0,2 (250ms), la fila pierde su filete, sus palabras reciben un bloque blanco y la primera imagen de la galería aparece fija en el centro de la pantalla, en las columnas 4–9, sin recortar.

ArchiveProjectList

Tarjeta

El marco de la galería del proyecto: 4:3 sobre negro, la primera imagen de la galería al 66% de ancho y en su proporción original sobre una copia desenfocada. NOMBRE en una etiqueta blanca a 10px de la esquina inferior izquierda. 4 columnas de ancho en escritorio (3 por fila) y todo el ancho en móvil. En reposo, la imagen en escala de grises sobre un fondo gris claro; el hover o el foco hacen aparecer el desenfoque y devuelven el color junto con el zoom; en color y con desenfoque en pantallas táctiles. El carrusel de Más proyectos usa la misma tarjeta. En hover o con el foco, la imagen se amplía a 1,06 sobre el desenfoque, que no se mueve (500ms, settle) y la etiqueta crece para mostrar el crédito (450ms, settle). Las demás no se atenúan. En móvil solo se ve la etiqueta con el NOMBRE.

ArchiveProjectGrid · ProjectCard

Banner de cookies · interactivo. En la web va fijo abajo; aquí se muestra en su sitio.

Cookies

Texto desde Site Global → Cookie Banner Text, con un enlace a la política de cookies.

Banner de cookies

A todo el ancho con los márgenes de 20px, blanco, filete arriba, 20px de relleno vertical y sin sombra. El interruptor de analíticas está en No por defecto; la palabra actual va en negro. “Configuración” pasa a “× Cerrar” y “Aceptar” pasa a “Guardar preferencias” cuando cambia el interruptor. Nunca es más alto que la pantalla: solo hace scroll la lista de ajustes, sin barra visible. Móvil: etiqueta, texto y las tres acciones a dos columnas cada una.

CommonCookieBanner

Footer

Cierra el Archivo, Sobre mí y las legales; nunca la home ni un proyecto. El footer de esta página es el ejemplo. Móvil: todo apilado en 1–6, los dos menús se leen como una sola tabla, 32px entre filas, “Última actualización” en 1–4 y “Arriba ↑” en 5–6.

CommonFooter · CommonLastUpdated

Páginas

Home

Pantalla completa, sin scroll, fondo negro, un proyecto destacado por gesto. Imagen a todo el ancho de las columnas 3–10 en escritorio y 1–6 en móvil, en su proporción original (sin recortar). Detrás, una copia desenfocada a sangre (120%, desenfoque de 60px, brillo 0,8). Pie a 20px del borde inferior, en blanco.

HomeFeaturedProjects · HomeProjectCaption · CommonMediaBlur

Archivo

Los controles en el bloque 2 de la cabecera; la cuadrícula (por defecto) o la lista. Búsqueda sin resultados: “Ningún proyecto coincide con “búsqueda”.” en Mute y luego “Borrar búsqueda”.

Proyecto

En escritorio la página no se mueve. Texto en 3–5: descripción; créditos, categorías (enlaces, una por línea) y stack en Mute; grupos a 24px; URL, sin etiqueta, anclada abajo. Galería en 7–12, un bucle vertical infinito que se mueve con la rueda desde cualquier punto. Año en Mute bajo el NOMBRE. Móvil: una columna, el NOMBRE y el año arriba y la galería debajo, sin bucle. Cerrar vuelve al Archivo con su búsqueda y su vista.

ProjectGalleryFrame

Más proyectos

“+ Más proyectos” fijo a 20px de la esquina inferior izquierda (sobre un bloque blanco en móvil), “+ Cerrar” mientras está abierto. Carrusel a 52px del borde inferior: 3 tarjetas visibles en escritorio y 2 en móvil, en bucle infinito a partir del siguiente proyecto. La página y el bloque 2 se atenúan a 0,2. Se cierra con Cerrar, Esc o un clic en la página atenuada.

ProjectMoreProjects

Sobre mí

Etiqueta en Mute en 1–2 y el contenido al lado; secciones a 96px (48px en móvil). Intro en 3–6 y retrato 4:3 en 9–12. Las filas de servicios alternan 4 y 6 columnas de ancho. Colaboración: todos los colaboradores, por orden alfabético, en 4 columnas, con un recuento de dos cifras en Mute que enlaza al Archivo filtrado; los que no tienen proyectos van en Mute, sin enlace. Biografía en 3–6. Docencia: una tabla de definiciones y luego “Ver programa ↗”. Contacto en 3–6 y la dirección en Mute en 9–10.

Legales

Texto corrido en 3–6: solo párrafos, listas y enlaces en el texto. Escritorio: título y “Última actualización” en el bloque 2 de la cabecera. Móvil: abren el contenido y el texto va 48px por debajo.

Error

Sin cabecera ni footer. Centrado y en mayúsculas. El enlace mantiene el idioma de la visita. Otros errores: “Lo sentimos, algo ha fallado. Vuelve a intentarlo más tarde.”

404
No se ha encontrado la página.

Ir a la página de inicio

Imagen y vídeo

Marco de la home · la proporción de la imagen
8 de 12 columnas / todo el ancho

Vista previa de la lista · el marco de galería
6 de 12 columnas; la imagen, 2/3

Marco de galería · 4:3, imagen en su proporción original (sin recortar) y 66% de ancho, sobre una copia desenfocada (40px)
2/3 de 6 columnas / 2/3 del ancho; también la tarjeta de proyecto de la cuadrícula del archivo y de Más proyectos, 4 de 12 columnas. Un vídeo va sobre el fondo gris.

Retrato de Sobre mí · 4:3
4 de 12 columnas / todo el ancho

Portada

Ninguna: la primera imagen de la galería hace sus veces en la home, la lista y la cuadrícula del archivo, Más proyectos y como imagen al compartir si el SEO del proyecto no tiene.

Imágenes

CDN de Sanity, srcset de 320–2400px, nunca más ancho que el original. Cada uso declara su ancho en sizes. Carga diferida por defecto; la primera diapositiva de la home y la primera imagen de cada proyecto cargan con prioridad alta.

CommonMediaImage

Vídeo

Sin sonido, en bucle, en línea, sin controles, object-fit: cover y en el mismo marco que la imagen. La imagen de debajo hace de póster y lleva el texto alternativo; el vídeo se oculta a las tecnologías de apoyo. Las tarjetas solo se reproducen mientras están a la vista.

CommonMediaLoop · VideoLoop

Imagen ausente

Deja a la vista el fondo negro del marco.

Imagen para compartir

1200×630, recortada alrededor del hotspot del CMS.

Movimiento

Reveal
--ease-reveal
cubic-bezier(0.76, 0, 0.24, 1)
Máscaras (cortinas) y diapositivas


Cortina de 1200ms de abajo arriba + zoom 1,14 → 1 en 1800ms

2026
ATLAS EDITORIAL
Diseño de Aitor Murillo

Settle
--ease-settle
cubic-bezier(0.2, 0.7, 0.2, 1)
Entradas, zoom y etiquetas que aparecen


Pie de la home: sube 8px y aparece en 600ms

Duraciones

--page-transition-duration 300ms: el fundido de página y cada color que cambia con él. El valor por defecto de Tailwind, 150ms y cubic-bezier(0.4, 0, 0.2, 1), para el color de los enlaces sin duración explícita.

Máscaras

Cortinas con clip-path: inset(). clip-to-top → clip-none descubre de arriba abajo desde el borde superior; clip-to-bottom → clip-none, de abajo arriba desde el borde inferior.

utils/wipe.js · wipeIn, wipeOut, zoomIn

Cambio de página

La página que sale se funde en 300ms y la nueva aparece en 300ms

El fondo y el color del texto de la cabecera y el fondo de la página cambian con el fundido de salida. La altura de la cabecera se mantiene mientras la página sale.

Diapositiva de la home

Cortina de 1200ms reveal; la imagen pasa de 1,14 a 1 en 1800ms; el fondo desenfocado se funde en 1400ms

Hacia delante, de abajo arriba; hacia atrás, de arriba abajo. El pie sale en 180ms ease-in; el nuevo sube 8px y aparece en 600ms settle, desde los 450ms. No se aceptan gestos durante la cortina.

Entrada del Archivo

Los elementos suben y aparecen por turnos (settle). Lista: 650ms, paso de 30ms, 8px. Cuadrícula: 900ms, paso de 60ms, 16px

La primera pantalla, en CSS desde el primer pintado y en cada cambio de vista; el resto sube al entrar en pantalla con el scroll, cada tanda por turnos. Retraso máximo de 1000ms por tanda. Filtrar no la repite.

Entrada de las páginas

Los bloques suben y aparecen por turnos (settle). 900ms, paso de 60ms, 16px, como la cuadrícula del Archivo

About, Legal y la guía de estilo, cada título y bloque de texto; el retrato de About mantiene su cortina. Primera pantalla y scroll como en el Archivo.

Vista previa de la lista

Entrada: cortina de 620ms reveal + zoom 1,1 → 1 en 1000ms. Salida: cortina de arriba abajo en 520ms

Al bajar por la lista descubre hacia arriba, y al subir, hacia abajo. Espera de 110ms; una cortina cada vez. Las imágenes sin decodificar esperan hasta 400ms. Atenuación de filas: 250ms.

Hover de tarjeta

Imagen 1 → 1,06, 500ms settle; fila del crédito 0fr → 1fr, 450ms settle

El tamaño del marco nunca cambia.

Más proyectos

Las tarjetas suben desde fuera de la pantalla, 800ms cubic-bezier(.7,0,.2,1), paso de 70ms

Al cerrar caen en orden inverso a 35ms. Las 8 primeras se escalonan. Atenuación de la página: 500ms.

Retrato de Sobre mí

Cortina de abajo arriba de 1200ms reveal + zoom 1,14 → 1 en 1800ms

Cuando la imagen ha cargado o ha fallado.

Menú móvil

El panel se descubre de arriba abajo en 700ms reveal; al revés al cerrar

El desenfoque de detrás se funde en los mismos 700ms.

Banner de cookies

Se descubre hacia arriba desde el borde inferior en 700ms reveal; vuelve abajo al cerrarse

También la primera vez que aparece.

Ajustes de cookies

La fila crece de 0fr a 1fr mientras la lista se descubre de arriba abajo, 700ms reveal

El resto del banner sube con ella.

Hover de color

150ms por defecto; 200ms en los botones de texto y las filas del footer

Movimiento reducido

Con prefers-reduced-motion: reduce se omiten todas las cortinas, zooms, escalonados, subidas, animaciones del carrusel y scrolls suaves: todo aparece y desaparece en su sitio. Los fundidos de color se mantienen.

Interacción

Home

Un proyecto por gesto: rueda o deslizamiento vertical de más de 30px (el gesto termina tras 160ms de pausa), o ↑ ↓ ← →.

Archivo

⌘K / Ctrl+K lleva el foco a la búsqueda (no si hay un diálogo abierto); Esc la borra y sale.

Proyecto

La rueda mueve la galería desde cualquier punto (escritorio). Esc cierra Más proyectos y luego el proyecto.

Más proyectos

La rueda vertical mueve el carrusel en horizontal. Al abrir, el foco va a la primera tarjeta real, y al cerrar vuelve al botón.

Táctil / sin hover

Sin atenuación ni vista previa en la lista, sin zoom ni crédito en las tarjetas.

URLs

/, /archive/, /about/, /archive/{slug}/, /legal/{slug}/, traducidas bajo /es/ y /ca/ (por ejemplo, /es/archivo/). La búsqueda y la vista no van en la URL; el botón Atrás funciona.

Enlaces cruzados

Una categoría en un proyecto, o un colaborador en Sobre mí, abre el Archivo con la búsqueda puesta.

Accesibilidad

Contraste

Todo el texto cumple WCAG AA (Mute 4,54:1 sobre blanco y 4,6:1 sobre negro). El azul nunca es texto sobre negro. El gris de filete nunca es texto.

Enlaces

Los enlaces en el texto van subrayados; dentro del texto corrido el color nunca es la única pista.

Semántica

nav para los menús, dialog para el menú móvil, time con datetime para años y fechas, dl para la docencia y role="switch" para los interruptores de cookies.

Encabezados

Un h1 por página: el nombre de la web en la home, oculto visualmente donde la cabecera ya muestra el título.

Oculto pero presente

La interfaz plegada o fuera de pantalla es inert (los ajustes de cookies y el carrusel cerrados). Las imágenes decorativas llevan alt="" o aria-hidden. Los pies ocultos de la home siguen siendo legibles.

Texto alternativo

Desde el CMS; si no hay, el título del proyecto en las galerías y la home, el nombre en el retrato de About y, en último caso, el nombre del archivo.

Foco

El menú móvil enfoca Cerrar; los ajustes de cookies, el primer interruptor (sin hacer scroll); Más proyectos, su primera tarjeta; Volver arriba, el primer enlace.

Regiones vivas

El recuento del Archivo se anuncia a medida que cambia la búsqueda.

Paridad con el teclado

Las vistas previas de la lista y las tarjetas reaccionan al foco igual que al hover.

Idioma

<html lang> sigue el idioma; los enlaces de idioma llevan lang y hreflang.

Pendiente

No hay anillo de foco visible: :focus-visible usa un contorno transparente, que el modo de colores forzados sí dibuja.

Aún sin hacer

Pendiente

No hay enlace para “saltar al contenido”.

Aún sin hacer

Implementación

Tokens y utilidades

--font-primary

fuente

Geist Mono, ui-monospace, monospace

--text-base, --text-base--line-height

tipografía

12px / 16px

--color-black · white · gray · gray-light · blue

color

#000 · #FFF · #767676 · #E6E6E6 · #0000EE

--ease-reveal, --ease-settle

curva

cubic-bezier(0.76,0,0.24,1) · cubic-bezier(0.2,0.7,0.2,1)

--page-transition-duration

duración

300ms

--page-content-top

maquetación

172px / 32vh

--header-height

maquetación (en ejecución)

Altura medida de la cabecera

--spacing-content-top

espaciado

24vh, desplazamiento del contenido del menú móvil

container

utilidad

Ancho máximo 100%, 20px de relleno lateral

main-grid

utilidad

6 / 12 columnas, separación de 10px

main-gap

utilidad

Separación de 10px

pt-page-content

utilidad

Inicio del contenido menos la altura de la cabecera

clip-to-top, clip-to-bottom, clip-none

utilidad

Estados de la máscara

stagger-rise

utilidad

Los hijos suben por turnos (--stagger-*; --index o su posición entre hermanos; data-own-entrance los excluye)

scrollbar-none

utilidad

Scroll sin barra visible

scripted:

variante

Solo se aplica cuando se ejecuta JavaScript

can-hover:

variante

Solo se aplica en dispositivos con hover