Ir al contenido

Logo y marca

La marca de mikroscope son nueve barras de muestra y la línea de su propia media, dibujadas en dos tonos sólidos por tema. Abajo: qué dice, cómo se genera y el contraste de cada tono contra el fondo sobre el que se dibuja, con el coste de esa decisión a su lado.

La marca es geometría, no un dibujo: nueve barras de muestra cuya envolvente es una ráfaga, cruzadas por la línea plana de su propia media. Esa es toda la tesis del proyecto en una forma: una media de un segundo informa de la línea, y el muestreo por debajo del segundo es lo que resuelve el pico que se alza sobre ella.

La ráfaga es asimétrica como lo es una real: tres muestras tranquilas, una subida rápida, el pico, una bajada más lenta y otras tres tranquilas. El pico queda en el centro de un número impar de barras, así que la marca se equilibra sobre su propio centro.

El generador dibuja la línea en la media aritmética de las alturas que recibe, no en un número elegido para que quede bien, y una barra toma el tono fuerte exactamente cuando está por encima de esa media. Así, la frase que dice la marca es una que el código hace cumplir: tres de las nueve muestras están por encima de su propia media, y son las tres a las que va el ojo. TestTheLineSitsAtTheMeanOfTheBars hace fallar la compilación si el dibujo y la aritmética se separan.

Medidos contra el fondo sobre el que se dibuja cada uno, con el contraste tal como lo define WCAG 2.2:

Tema Fondo Por encima de la media En la media o por debajo, y la línea Separación
Oscuro #0e1316 #fbbf24 11,20:1 #c2740a 5,16:1 2,17:1
Claro #ffffff #633009 10,73:1 #b45309 5,02:1 2,14:1

Una paleta por tema no es un refinamiento; es la única forma de que la marca se lea en ambos. Un ámbar lo bastante claro para leerse sobre la página casi negra da 1,67:1 sobre blanco (#fbbf24), y uno lo bastante oscuro para el blanco desaparece en la página oscura. Sobre blanco, la muestra que está por encima de la media es el tono más oscuro, así que la marca se lee en el mismo sentido en los dos temas.

TestEveryToneClearsAAInItsOwnTheme vuelve a calcular los contrastes a partir del hexadecimal en cada ejecución y hace fallar la compilación si algún tono da menos de 4,5:1 sobre su propio fondo, o si los dos tonos de un tema están a menos de 2,0:1 entre sí. Un tono editado sin comprobarlo rompe la compilación en vez de publicarse. TestNothingInTheMarkDependsOnOpacity vigila la otra mitad de la decisión.

Una barra tranquila dibujada con el color fuerte a una opacidad baja se ve bien y falla. Compuesto sobre la página, un 0,28 de #f59e0b da 1,73:1 sobre el fondo oscuro y un 0,42 de #a16207 da 1,80:1 sobre blanco, donde AA pide 4,5:1. Llegar a 4,5 subiendo el alfa exige 0,68 en el tema oscuro y 0,96 en el claro, y entonces una barra tranquila es una barra fuerte y la única distinción que la marca existe para hacer desaparece. Así que la separación son dos tonos sólidos.

Eso cuesta fuerza. Sólido contra sólido da unos 2,1:1 entre los dos grupos; dibujar la barra tranquila a 0,28 (0,42 sobre blanco) los separa unos 5:1 en el tema oscuro y 2,7:1 en el claro, con alfas que dan 1,73:1 y 1,80:1 contra su propia página y por tanto no llegan a AA. Lo que se gana es que nada en la marca se compone contra un fondo que este repositorio no controla (un README en GitHub, un og:image en un cliente de chat, un favicon sobre la interfaz del navegador), de modo que cada número de la tabla es el número que de verdad recibe el lector.

WCAG 1.4.11 pide 3:1 a un objeto gráfico, y 1.4.3 exime a los logotipos de cualquier mínimo. 4,5:1 en cada barra es una norma de la casa más estricta que el estándar, elegida por el mantenedor del proyecto, José Manuel Requena Plens, frente al cambio menor de subir los alfas hasta 3:1.

El ámbar también significa umbral en los paneles de este proyecto, donde un panel se pone naranja antes de ponerse rojo. Los dos no chocan literalmente (los paneles usan los colores con nombre propios de Grafana y nunca estos hexadecimales), pero a un lector que ha aprendido en un panel que “ámbar significa mira esto” se le pide leer el mismo tono en la marca del proyecto. Ese es el coste de la elección, hecha a sabiendas.

Las alturas de las barras no son una captura real. Una ráfaga que midió mikroscope tuvo un pico de 736 paquetes en una muestra de 20 ms frente a una mediana de 28, y 26× es un rango que ningún cuadrado por sí solo puede representar: las muestras tranquilas se reducen a puntos, o una escala logarítmica aplana precisamente el pico que la marca existe para mostrar. Las alturas de la marca son proporciones de la altura dibujada.

Nueve barras a dieciséis píxeles son un borrón, así que el favicon baja a cinco y conserva el pico por encima de la línea, que es la parte que lleva el significado.

El favicon.svg del sitio es el único icono sin fondo propio. Lleva las dos paletas y cambia según el prefers-color-scheme del propio lector, la señal que sigue la propia interfaz del navegador, así que dibuja #fbbf24/#c2740a sobre una interfaz oscura y #633009/#b45309 sobre una clara. Cada imagen rasterizada lleva en cambio su propio fondo #0e1316, porque un .ico no tiene forma de preguntar.

La marca vive como un generador, cmd/gen_brand/, y no como una carpeta de ficheros dibujados a mano, porque así cambiar la paleta o el número de barras es una edición en vez de nueve en cada uno de una docena de ficheros. Es una herramienta de tiempo de compilación y no es uno de los dos binarios publicados. Desde la raíz del repositorio:

Ventana de terminal
go run ./cmd/gen_brand mark -out brand # la marca y el favicon, por tema
go run ./cmd/gen_brand compose -out brand # el banner, la imagen social y el og:image
go run ./cmd/gen_brand icons -out site/public # el favicon, los iconos táctiles y el manifiesto de aplicación web

mark es texto puro. compose lee los tres fondos bg-*.png del directorio en el que escribe y llama a rsvg-convert para los PNG que se publican. icons llama a rsvg-convert y a ImageMagick para el .ico, y es el único que escribe fuera de brand/. Cada coordenada se escribe con dos decimales, redondeada al más cercano y, en caso de empate, al par, así que los ficheros están pensados para reproducirse byte a byte en cualquier máquina; TestMarkIsByteForByteReproducible comprueba que dos ejecuciones en el mismo equipo dan los mismos cuatro ficheros de marca y de favicon.

Fichero Dónde Suborden Qué es
mark-dark.svg, mark-light.svg brand/ mark La marca, una por tema
favicon-dark.svg, favicon-light.svg brand/ mark La variante de cinco barras, una por tema
mark-inline.svg brand/ mark La marca para una página que la incrusta: el tono fuerte es currentColor, el tranquilo --ms-mark-quiet
favicon-inline.svg brand/ mark El favicon para una página que lo incrusta, el gemelo en línea de favicon.svg
banner.svg y .png brand/ compose 1280×320, para el README
social.svg y .png brand/ compose 1280×640, la vista previa social del repositorio
og.svg y .png brand/ compose 1200×630, el og:image de la documentación
background.png brand/ ninguna El campo generado del que se recortan las tres composiciones
bg-banner.png, bg-social.png, bg-og.png brand/ ninguna Esos recortes, que lee compose
favicon.svg site/public/ icons Las dos paletas, cambiando según prefers-color-scheme
site.webmanifest site/public/ icons El manifiesto de aplicación web: nombra las imágenes de 192, 512 y la enmascarable, con URL relativas
favicon.ico site/public/ icons Tres dibujos, a 16, 32 y 48 px, en vez de uno escalado de tres formas
apple-touch-icon.png, icon-192.png, icon-512.png site/public/ icons 180, 192 y 512 px, cada uno dibujado a su propio tamaño
icon-maskable-512.png site/public/ icons Con más margen, para quedar dentro del círculo de 80 % del ancho del icono al que un lanzador puede recortar

La cabecera de cada página enlaza favicon.svg, favicon.ico, apple-touch-icon.png y site.webmanifest. El enlace al .ico dice sizes="32x32", lo que mantiene a Chromium solo en el SVG: Chromium 153 sin interfaz pidió únicamente favicon.svg. El manifiesto nombra icon-192.png, icon-512.png e icon-maskable-512.png con URL relativas a él mismo, y deja fuera favicon.svg, el único icono sin fondo propio, porque lo que acaba en una pantalla de inicio lleva el suyo. No lleva id, que se resuelve contra el origen de start_url y no contra el manifiesto: Chromium 153 resolvió ./ a la raíz del origen, aquí https://jmrplens.github.io/, la dirección que ya reclama el sitio central del dominio con un manifiesto propio, y un id que se quede dentro de este sitio tiene que escribir /mikroscope/, la ruta base que nada más en el manifiesto nombra. Sin él, toma el valor de start_url, que Chromium resuelve a /mikroscope/, el id que recomienda.

Una sola etiqueta theme-color da el color de la cabecera que está en pantalla, #151c20 en oscuro y #fafbfb en claro. Sigue al tema del sitio, no al esquema del sistema: se sirve con la cabecera oscura, el tema que conserva una página sin JavaScript diga lo que diga el sistema, y un script de la cabecera del documento la pasa a la clara cada vez que la página se vuelve clara, por el esquema del sistema, el selector de tema, una elección guardada o el botón del teléfono. Chrome lee la etiqueta; Safari 26, según informes públicos y sin probarlo aquí, la ignora y toma el color de la cabecera fija. En Chromium y WebKit sin interfaz, con los dos esquemas, tras elegir en el selector, tras una elección guardada y una recarga, tras el botón del teléfono y sin JavaScript, la etiqueta tuvo el color de la cabecera todas las veces; el par de etiquetas separadas por prefers-color-scheme al que sustituye tenía el color del otro tema tras cada elección, y en un sistema claro sin JavaScript. No se ha probado en un dispositivo si el Chrome de un teléfono repinta su barra en cuanto cambia la etiqueta.

TestTheCommittedWebFilesMatchTheGenerator compara favicon.svg y site.webmanifest de site/public/ con lo que el generador escribe ahora, así que un cambio sin regenerar hace fallar make test; los PNG dependen de los conversores instalados y no se comparan. Sin probar: un teléfono real, una instalación en la pantalla de inicio y cómo recorta de verdad un lanzador el icono enmascarable.

La marca de la cabecera de este sitio es favicon-inline.svg, el dibujo de cinco barras, pintada con la paleta propia del sitio; mark-inline.svg ocupa el hueco del hero. En ambos casos el dibujo de la interfaz es el dibujo de brand/.

No lo escribe el generador: background.png se generó una vez con inference.sh (openai/gpt-image-2, 1536×1024, quality: high, 0,16 $) y se conserva como imagen rasterizada. Todo lo que se dibuja encima es vectorial, así que el texto se mantiene nítido al tamaño al que se produzca la imagen. El prompt pedía un campo casi negro de barras de muestra verticales y tenues, cada vez más densas y cálidas hacia la derecha, y que el tercio izquierdo quedara vacío, que es donde van la marca y el texto, así que la composición nunca pelea con su propio fondo.

Los tres recortes conservan todo el degradado de izquierda a derecha en vez de tomar una ventana del centro:

Ventana de terminal
magick background.png -resize 1280x -gravity center -crop 1280x320+0+0 +repage bg-banner.png
magick background.png -resize 1280x -gravity center -crop 1280x640+0+0 +repage bg-social.png
magick background.png -resize 1200x -gravity center -crop 1200x630+0+0 +repage bg-og.png

Las composiciones son claras sobre oscuro de principio a fin, así que toman los dos tonos del tema oscuro y no necesitan pareja de temas. Medidos sobre el fondo más oscuro del propio campo (#020608, muestreado del borde izquierdo), el título #f6f3ee da 18,38:1, el lema #cfc6b8 12,04:1, y los dos tonos de la marca 12,19:1 y 5,62:1: más que en la página, porque el campo es más oscuro que ella. El lema es “Sub-second kernel telemetry from inside the router”.

A mano: Settings, luego Social preview, y subir social.png. GitHub no ofrece ninguna API para ello.