extraído de aristidebenoist.com Ver sitio ↗

Aristide
Benoist

Un portfolio que no es una página: es un instrumento. El DOM cabe en cuatro esquinas (logo, about, metadata, contacto) y todo lo demás es un motor WebGL propio: una tira de película con los proyectos en slices verticales que se arrastra con inercia, se inclina con la velocidad y se expande a pantalla completa al entrar.

Bicolor estricto: negro elevado #141414 y una tinta hueso verdoso #BAC4B8 que baja la temperatura de todo el sitio (10.2:1 AAA, clave cuando el cuerpo de texto real mide 11px). Sin GSAP, sin Three.js: la física del arrastre está escrita a mano en un único bundle, y cada proyecto trae su propio color de acento como inquilino temporal.

dark mode bicolor #141414 + #BAC4B8 webgl propio drag con inercia cero radios cero sombras todo uppercase
↓ Scroll
Independent developer
Motion & interaction
Email · Instagram · Twitter
Paris, FR
aristidebenoist.com
Captura del home de Aristide Benoist: la tira de película desplegada por todo el ancho tras un arrastre, slices atenuadas sobre negro
La tiraSlices verticales de los case studies, atenuadas al ~35% de brillo. La captura la muestra desplegada por el ancho completo tras un drag: su estado más característico.
El chromeLogo "ARISTIDE" en Timmons NY a 50px, ticks de navegación arriba al centro, metadata de 11px en las esquinas. No hay nada más en el DOM.
La luzBrillo 1.0 = interactivo. Lo que está a plena luz se puede tocar; lo atenuado duerme. Es la jerarquía entera del sitio.
01

Color

dark · bicolor + inquilinos
Sistema (los únicos colores fijos)
#141414
Negro elevado
lienzo único del sitio; nunca #000 de fondo
hueso encima: 10.2:1 AAA
#BAC4B8
Hueso verdoso
LA tinta: logo, metadata, links, ticks; y superficie del about invertido
sobre #141414: 10.2:1 AAA · negro encima: 11.7:1 AAA
#1E1E1E
Panel
superficie secundaria: backdrop de slices y listados
hueso encima: 9.3:1 AAA
#CC9933
Dorado
único acento editorial propio (etiquetas destacadas, "NEW")
sobre #141414: 7.2:1 AA (AAA en display)
#000000
Negro puro
solo texto sobre el panel hueso; nunca fondo de sección
sobre hueso #BAC4B8: 11.7:1 AAA
Acentos por proyecto (inquilinos: uno a la vez, medidos en el DOM)

Cada case study define su pareja fondo/acento (rosa #FF71CB, verde #53BB89, rojo #F04333, crema #FFF1CE…) y la trae consigo al expandirse. La regla de los inquilinos: nunca dos acentos a la vez en pantalla, nunca un acento como color de UI global. Cuando la tira se repliega, el sitio vuelve a ser bicolor. Pasa el cursor por la banda: la luz es el estado.

Contraste verificado
#FF71CB
Rosa flúor
acento de proyecto
sobre #141414: 7.4:1 AA
#53BB89
Verde
acento de proyecto; sirve de éxito derivado
sobre #141414: 7.8:1 AA
#F04333
Rojo
acento de proyecto; sirve de error derivado
sobre #141414: 4.9:1 AA solo texto grande
#D2DCF2
Cielo
acento claro de proyecto
sobre #141414: 13.5:1 AAA
02

Typography

monumental o microscópico
Aristide 50.
Anton + Archivo Original: TIMMONS NY 2.0 (Matt Willey) y JWStudio Sans Bold -> HTML: Anton + Archivo (Google substitutes)
Display · Anton (orig. Timmons NY)Independent developer
Micro 12px · Archivo 700 (orig. jws)Aristide Benoist is a developer who specializes in motion and interaction
Micro 11px · lh 10px (real)Available Apr. 2023 · Paris, FR · Email / Instagram / Twitter
Micro-etiqueta · 11-12px / 700 / uppercase / lh ≤ 0.91

El cuerpo de texto real del sitio mide once píxeles con line-height de diez: leyendas de museo, más apretadas que su propio cuerpo. No existe el 16px normal. La jerarquía salta de esto directamente al cartel: un factor de 4.5 a 20 veces sin escalas intermedias.

Todo el sitio va en mayúsculas: no hay una sola palabra en caja baja.

RolSize realLHWeightTracking
título de proyecto (canvas)~14vw0.85400-0.02em
logotipo "ARISTIDE"50px44px (0.88)400-1px
número de índice50px44px400-0.5px
link de chrome12px34px700-0.24px
metadata11px10px (0.91)700normal
cuerpo de lectura(no existe)

Cinco tamaños y ningún cuerpo de lectura. Para documentación (como esta página) se deriva un único intermedio: 15px / 1.6 en Archivo 400-500, y nada más.

Original: TIMMONS NY 2.0 (display) y JWStudio Sans Bold (micro-etiquetas) -> HTML: Anton y Archivo (Google substitutes). Los @font-face reales ofuscan los nombres ("TNY" y "jws"); los originales se recuperaron de las tablas name de los woff2: Timmons NY 2.0 es la titling ultra-condensada de Matt Willey para el New York Times Magazine, y JWStudio Sans Bold es una grotesca de Jon Way Studio (2017) servida solo en Bold. Para el display se compararon Oswald (asta demasiado ligera) y Bebas Neue (terminales suaves, aire de plantilla): gana Anton por el peso de asta macizo y la vocación de cartel apilado. Para las micro-etiquetas se compararon Inter (a 11px uppercase parece dashboard) y Roboto Condensed (esqueleto blando): gana Archivo en 600/700 por su x alta y su mancha densa. Mono: no detectada en el sitio.
03

Components

texto, línea de 1px y luz
Aristide

El chrome completo del sitio: logotipo en titling a 50px (tracking -1px), el navegador de ticks (una marca de 1px por proyecto; la activa crece; es un scrubber, no una lista de links) y los links de 12px con subrayado que se redibuja: sale por un extremo y entra por el otro con cubic-bezier(0.25, 0.46, 0.45, 0.94). Ningún componente tiene fondo, borde o radio.

La slice de película: columna vertical a canto vivo, brightness .35 en reposo. El hover la ilumina al 100%, la ensancha y revela el título en la titling. En el sitio real este componente vive en WebGL con física de arrastre; el click la expande a pantalla completa y el case study hereda el lienzo.

Independent developer
specialized in motion
and interaction
Available Apr. 2023
Paris, France
Panel about · la inversión

The negative

El único momento claro del dominio: el hueso #BAC4B8 pasa de tinta a superficie y el texto baja a negro puro (11.7:1 AAA). No es un tema claro: es el negativo fotográfico exacto del sitio.

Metadata de esquina: bloques de 11px / lh 10px anclados al frame del viewport, como los créditos de un cartel de cine. El panel about cubre la pantalla con canto recto: sin arco, sin fade, un corte de negativo.

04

Motion & interaction

física a mano, sin librerías

Drag con inercia + skew de velocidad

La tira sigue al puntero con lag (lerp ~0.1) y al soltar continúa con decaimiento (~0.92 por frame). Cada slice se inclina proporcionalmente a la velocidad instantánea y vuelve a la vertical al frenar: el sello del motor.

La luz como estado

Las imágenes viven al ~35% de brillo y despiertan al 100% bajo el cursor, en 400-600ms con easeOutQuad. Donde otros sistemas elevan con sombra, este ilumina: brillo pleno significa "tocable".

Navegador de ticks (scrubber)

Una marca vertical de 1px por proyecto, arriba al centro. Recorrer la fila desplaza la tira proporcionalmente con la misma inercia. No es un menú: es la línea de tiempo de la película.

Expansión como router + inversión

Entrar a un proyecto no es cambiar de página: la slice crece hasta cubrir el viewport (~900ms) y el case study hereda el lienzo con su acento. El about, en cambio, entra como negativo: un panel hueso con canto recto.

TokenValorUso
easeOutQuad (real, CSS)cubic-bezier(0.25, 0.46, 0.45, 0.94)paneles, subrayados redibujados, hovers
easeOutSine (real, CSS)cubic-bezier(0.39, 0.575, 0.565, 1)fades de metadata y chrome
lerp del drag (derivado)~0.08-0.12 por frameseguimiento del puntero en el motor WebGL
fricción (derivado)~0.92 por framedecaimiento de la inercia al soltar
iluminación400-600msbrightness .35 → 1.0 en hover
expansión~900msslice → case study a pantalla completa
intro~1800ms staggerla tira se construye slice a slice

Stack real: ninguno. Sin GSAP, sin Three.js, sin Lenis, sin Locomotive (verificado en runtime: ningún global expuesto). Todo el motor (render WebGL, física, router, precarga) vive en un único bundle propio, /static/js/d.js. Los dos cubic-bezier del CSS son lo único declarativo; el resto es requestAnimationFrame. Con prefers-reduced-motion: tira desplegada y a brillo .6, navegación por teclado sin skew ni inercia, expansión en corte directo.

05

Spacing & shape

frame perimetral · canto vivo
El layout es un marco, no una columna
8px · micro-gap entre líneas de metadata
~1vw · gap entre slices
frame · clamp(40px, 3.5vw, 56px)
tira en reposo · ~31vh de alto

Sin max-width, sin contenedor de lectura, sin scroll vertical en la home: el plano es fijo (100vw × 100vh), el eje de exploración es horizontal (drag) y la profundidad es el zoom. El vacío central no es espacio muerto: es el escenario de la física.

Familia de formas
0 · todo
Elevación
border-radius: 0 en todo el sitio (verificado)
box-shadow: ninguna (verificado)
borde: solo subrayados de 1px

niveles de profundidad:
0 · lienzo #141414 plano
1 · atenuación (brightness .35)
2 · luz (brightness 1.0 = tocable)
3 · expansión (el zoom es la navegación)
± · inversión (#BAC4B8 + negro, el negativo)
06

Principles

guardrails

    Do

  • Mantén el bicolor estricto: lienzo #141414 + tinta hueso #BAC4B8. Un tercer color solo puede ser el acento de UN proyecto activo.
  • Compón todo en mayúsculas y en dos escalas extremas: titling monumental (lh ≤ 0.88, tracking negativo) o micro-etiqueta densa (11-12px).
  • Ancla el DOM al perímetro: esquinas y centro superior; el interior del frame pertenece al contenido.
  • Usa la atenuación como jerarquía: reposo al ~35% de brillo, activo al 100%. La luz sustituye al color de estado.
  • Canto vivo en todo: radio 0, cero sombras, y el subrayado de 1px como único borde.
  • Dale física al movimiento: inercia al soltar, skew proporcional a la velocidad, expansión con easeOutQuad.
  • Si necesitas un momento claro, invierte (hueso de fondo, negro de texto): nunca un gris intermedio.

    Don't

  • No conviertas las micro-etiquetas en texto de 14-16px: la tensión monumental/microscópico ES el sistema.
  • No añadas border-radius ni box-shadow: el original tiene exactamente cero de cada.
  • No uses blanco puro como tinta: el hueso #BAC4B8 es la temperatura de sala de cine; el blanco vibra.
  • No pongas dos acentos de proyecto a la vez: son inquilinos con contrato de exclusividad temporal.
  • No compongas el display con line-height ≥ 1: la titling se apila (0.85-0.88) o deja de ser cartel.
  • No sustituyas el drag por un carrusel con flechas: la tira es un instrumento físico, no una galería paginada.
  • No ilumines nada no interactivo: brillo pleno significa tocable; una imagen decorativa a plena luz miente.
07

Resources

copy & paste
:root {
  /* sistema bicolor */
  --color-background: #141414;   /* negro elevado, nunca #000 de fondo */
  --color-ink: #BAC4B8;          /* hueso verdoso: LA tinta (10.2:1 AAA) */
  --color-panel: #1E1E1E;
  --color-inverse-bg: #BAC4B8;   /* el about: negativo exacto */
  --color-inverse-text: #000000;
  --color-gold: #CC9933;         /* único acento editorial propio */

  /* acentos POR PROYECTO: uno a la vez, solo con su proyecto activo */
  --project-pink: #FF71CB;
  --project-rose: #D99299;
  --project-plum: #321D44;
  --project-umber: #734130;
  --project-navy: #1E1F28;
  --project-sky: #D2DCF2;
  --project-green: #53BB89;
  --project-sand: #E0C8A4;
  --project-bone: #D4C3A5;
  --project-red: #F04333;
  --project-blush: #FEA8B1;
  --project-cream: #FFF1CE;

  --font-display: "Anton";       /* sustituta de TIMMONS NY 2.0 */
  --font-body: "Archivo";        /* sustituta de JWStudio Sans Bold */

  /* formas: no hay */
  --radius: 0;
  /* sombras: no hay */

  /* easings reales del chrome DOM */
  --ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --ease-out-sine: cubic-bezier(0.39, 0.575, 0.565, 1);

  /* jerarquía por luz */
  --brightness-idle: 0.35;
  --brightness-active: 1.0;
  --duration-light: 500ms;

  --frame: clamp(40px, 3.5vw, 56px);
  --strip-height: 31vh;
}
@theme {
  --color-canvas: #141414;
  --color-ink: #BAC4B8;
  --color-panel: #1E1E1E;
  --color-gold: #CC9933;
  --color-inverse: #BAC4B8;
  --color-inverse-ink: #000000;

  --color-project-pink: #FF71CB;
  --color-project-green: #53BB89;
  --color-project-red: #F04333;
  --color-project-sky: #D2DCF2;
  --color-project-cream: #FFF1CE;
  --color-project-plum: #321D44;

  --font-display: "Anton", "TIMMONS NY 2.0", "Arial Narrow", Impact, sans-serif;
  --font-body: "Archivo", "JWStudio Sans", Helvetica, Arial, sans-serif;

  --radius-none: 0px;

  --ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --ease-out-sine: cubic-bezier(0.39, 0.575, 0.565, 1);

  --spacing-frame: clamp(40px, 3.5vw, 56px);
  --spacing-strip: 31vh;
}

/* Reglas de uso:
   - todo uppercase; display lh 0.85-0.88; micro-etiquetas 11-12px
   - cero border-radius, cero box-shadow
   - jerarquía por luz: brightness .35 en reposo, 1.0 en hover */
{
  "colors": {
    "canvas": "#141414",
    "ink": "#BAC4B8",
    "panel": "#1E1E1E",
    "gold": "#CC9933",
    "inverse": { "bg": "#BAC4B8", "text": "#000000" },
    "projects": {
      "pink": "#FF71CB",
      "rose": "#D99299",
      "plum": "#321D44",
      "umber": "#734130",
      "navy": "#1E1F28",
      "sky": "#D2DCF2",
      "green": "#53BB89",
      "sand": "#E0C8A4",
      "bone": "#D4C3A5",
      "red": "#F04333",
      "blush": "#FEA8B1",
      "cream": "#FFF1CE"
    },
    "rule": "bicolor system; project accents are tenants, one at a time"
  },
  "typography": {
    "display": {
      "original": "TIMMONS NY 2.0 (Matt Willey)",
      "substitute": "Anton",
      "logo": { "fontSize": "50px", "lineHeight": "44px", "letterSpacing": "-1px" },
      "title": { "fontSize": "clamp(80px, 14vw, 220px)", "lineHeight": "0.85", "letterSpacing": "-0.02em" },
      "case": "uppercase"
    },
    "micro": {
      "original": "JWStudio Sans Bold (Jon Way Studio)",
      "substitute": "Archivo 600/700",
      "meta": { "fontSize": "11px", "lineHeight": "10px", "fontWeight": 700 },
      "link": { "fontSize": "12px", "lineHeight": "34px", "letterSpacing": "-0.24px", "fontWeight": 700 },
      "case": "uppercase"
    },
    "rule": "no reading size exists; derived doc body = 15-16px/1.6 Archivo 400"
  },
  "rounded": { "all": "0px" },
  "shadow": { "all": "none" },
  "motion": {
    "engine": "custom WebGL bundle (/static/js/d.js), no GSAP/Three/Lenis",
    "ease-out-quad": "cubic-bezier(0.25, 0.46, 0.45, 0.94)",
    "ease-out-sine": "cubic-bezier(0.39, 0.575, 0.565, 1)",
    "physics": { "lerp": "0.08-0.12", "friction": "0.92/frame" },
    "durations": { "light": "400-600ms", "expand": "~900ms", "intro": "~1800ms" },
    "brightness": { "idle": 0.35, "active": 1.0 }
  },
  "layout": {
    "frame": "clamp(40px, 3.5vw, 56px)",
    "strip-height": "31vh",
    "strip-gap": "~1vw",
    "micro-gap": "8px",
    "rule": "perimeter frame; DOM in corners; canvas owns the center"
  }
}