El portfolio que no se lee: se conduce. Un camión 4x4 sobre un suelo violeta cuadriculado con cruces de neón, un aro de luz que dice por dónde empezar y un rótulo escrito a mano: CLICK TO START.
Fue Site of the Year en Awwwards y sigue siendo el ejemplo canónico de "portfolio como videojuego". La regla de color del mundo es simple: violeta #553DFF para el espacio (neón, árboles, rejilla), ámbar #FFA201 para la vida (farolas, luces del camión). La versión actual renderiza con WebGPU y lo presume con una insignia lima en el HUD. Todo tiene física: chocar es la micro-interacción principal.
Nada de esto existe en CSS: el :root del sitio tiene cero variables y el body es transparente porque la escena Three.js pinta el color. Estas paradas están muestreadas píxel a píxel de la captura 1600x900. La trampa del neón: el violeta #553DFF brilla muchísimo pero solo rinde 3:1 sobre el suelo; en el sitio real nunca es texto, es tubo, árbol y rejilla.
Amatic SC rotula, Nunito conversa, Pally instrumenta. Los "botones" del mundo (Interact, Unstuck) son rótulos manuscritos de 64px sin caja ni fondo; los mensajes de visitantes van a 50px y los títulos de panel a 40px. Nunito hace todo lo demás a 20px redondos y amables (es el font-size del body entero). La diferencia entre rotular y conversar es la firma tipográfica del sitio.
Sin tracking y sin line-height forzado: todo va con letter-spacing normal (medido) y la métrica nativa de cada familia. La personalidad la ponen los esqueletos.
| Rol | Size real | Weight | Familia | Uso |
|---|---|---|---|---|
| letrero | 64px | 700 | Amatic SC | Interact / Unstuck |
| whisper | 50px | 700 | Amatic SC | mensajes de visitantes |
| title | 40px | 700 | Amatic SC | paneles (Devlogs...) |
| body | 20px | 400 | Nunito | conversación |
| body sm | 16px | 400 | Nunito | notas al 80% |
| label | 13px | 700 | Nunito | chips del HUD |
| hud | 20px | 500 | Pally | piezas con voz propia |
Botón-letrero (componente firma): los controles del mundo no tienen caja. Amatic SC 700 a 64px, transparente, borde cero y radio cero (todo medido del DOM real). Son letreros pintados que flotan sobre la escena; el hover les da rebote. Si un control vive dentro del mundo, no lleva superficie: las cajas son para paneles que pausan el juego. Unstuck existe porque volcar el camión es parte del juego.
Aro de inicio: la zona de acción no es un botón flotante, es un tubo de neón en el suelo. Núcleo #FFFCFF de 2-3px, halo #553DFF, el interior iluminado a #6C4EB2 y bloom real en la escena. El rótulo de instrucción se dibuja a mano junto al aro, en el mundo, no en un tooltip.
Insignias del HUD (reales): el estado técnico se muestra con orgullo y color caramelo. "High" al 80% de blanco, "WebGPU" en lima #D5FF95 (la insignia del motor es parte de la marca), "Offline" en rosa #FF6A7C. Los chips de input (Mouse Keyboard, Mobile Tablet, gamepad con iconos Xbox reales en el DOM) usan Nunito 700 a 13px; el icono de mando lleva radio 15px medido.
Whispers are messages left by visitors.
- Everyone can see them · - They stay painted on the floor
Panel de contenido: cuando algo interrumpe el juego (whispers, menú, leaderboard) sí hay superficie: violeta profundo al 92%, radio 12px, título Amatic 40px, body Nunito 20px, notas a 16px al 80% y un divisor de 1px blanco (el div.line real). El input de whispers escribe en Amatic a 50px y el mensaje queda pintado en el suelo del mundo. El HUD real también avisa en rosa: "Server currently offline. Scores can't be saved." y "Resets in..." para el reinicio de récords.
Chasis + 4 ruedas con suspensión, derrape y vuelco. La simulación no usa duraciones: usa masas, fuerzas y amortiguación. La cámara cenital sigue al camión con lag suave (lerp) para que el mundo gire alrededor. Volcar no es un error: es la razón de que exista el botón Unstuck.
La versión actual renderiza con WebGPU cuando el navegador puede y cae a WebGL cuando no. El HUD lo presume con la insignia lima y expone el ajuste de calidad (High). El estado técnico es celebración, no letra pequeña.
Bolos, vallas y letras del suelo tienen cuerpo físico: chocar es la micro-interacción principal. La instrucción real del intro lo dice: "And don't break anything!". Cada adorno del mundo es jugable o no existe.
Las zonas de acción laten con bloom: el aro de inicio es un tubo de luz (núcleo #FFFCFF, halo #553DFF), no un borde CSS. El suelo dentro del aro se ilumina. Lo que importa emite luz; lo que descansa la recibe.
Teclado, touch (joystick + botones táctiles reales, js-touch-buttons) y gamepad con iconos Xbox en el DOM. El sitio detecta el esquema de entrada y muestra chips explicativos. El clic inicial del CLICK TO START también desbloquea el audio: motor, colisiones y bocina ligados a la simulación.
Los whispers son mensajes de visitantes pintados en el suelo (Amatic 50px) que se atraviesan conduciendo; el leaderboard cronometra vueltas con reset programado ("Resets in") y avisa en rosa si el servidor está caído. Lo social vive en el mundo, no en un muro de comentarios.
Accesibilidad: con prefers-reduced-motion, la cámara sigue rígida (sin lag), el neón no late (brillo fijo) y los letreros entran por opacidad. Los paneles de contenido (Three.js, Three.js Journey, Devlogs, Source code, Musics: títulos H2 reales del DOM) ofrecen el portfolio en HTML navegable, con lo que el CV es legible sin conducir.
:root {
--color-primary: #553DFF; /* violeta neon: espacio, tubo, arboles */
--color-secondary: #FFA201; /* ambar: farolas, focos de vida */
--color-background: #1E0B43; /* el suelo del mundo (muestreado) */
--color-background-deep: #1D063B;
--color-surface: #2A1155; /* paneles (derivado) */
--color-neon-core: #FFFCFF; /* nucleo del tubo de neon */
--color-grid-cross: #4129EA; /* las marcas x del suelo */
--color-tree: #6D54D3; /* vegetacion neon */
--color-floor-glow: #6C4EB2; /* suelo dentro del aro */
--color-magenta: #4118B4; /* vinieteo de esquinas */
--color-lamp-bright: #FFFF91; /* pico del cono de la farola */
--color-text-primary: #FFFFFF;
--color-text-faded: rgba(255, 255, 255, 0.8);
--color-danger: #FF6A7C; /* real: "Offline" del HUD */
--color-danger-soft: #FF87A2; /* real: aviso de servidor */
--color-success: #D5FF95; /* real: insignia WebGPU */
--color-warning: #FFA201;
--color-info: #6D54D3;
--font-display: "Amatic SC", cursive; /* Google, directa */
--font-body: "Nunito", sans-serif; /* Google, directa */
--font-hud: "Fredoka", "Pally", sans-serif; /* sustituta de Pally */
--radius-chip: 15px; /* real: icono de gamepad del HUD */
--radius-panel: 12px; /* derivado */
--radius-letrero: 0; /* real: los botones del mundo no tienen caja */
--radius-ring: 100%;
--shadow-none: none; /* el DOM real no usa box-shadow */
--glow-neon: 0 0 8px #FFFCFF, 0 0 24px #553DFF, 0 0 64px rgba(65, 41, 234, 0.5);
--glow-amber: 0 0 16px #FFA201, 0 0 48px rgba(255, 162, 1, 0.4);
--space-base: 4px;
--space-xs: 8px;
--space-sm: 12px;
--space-md: 16px;
--space-lg: 24px;
--space-edge: 40px;
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-follow: cubic-bezier(0.25, 0.1, 0.25, 1);
--duration-pop: 350ms;
--duration-panel: 450ms;
--duration-pulse: 1600ms;
}@theme {
--color-primary: #553DFF;
--color-secondary: #FFA201;
--color-background: #1E0B43;
--color-background-deep: #1D063B;
--color-surface: #2A1155;
--color-neon-core: #FFFCFF;
--color-grid-cross: #4129EA;
--color-tree: #6D54D3;
--color-floor-glow: #6C4EB2;
--color-magenta: #4118B4;
--color-lamp-bright: #FFFF91;
--color-text-primary: #FFFFFF;
--color-danger: #FF6A7C;
--color-danger-soft: #FF87A2;
--color-success: #D5FF95;
--color-warning: #FFA201;
--color-info: #6D54D3;
--font-display: "Amatic SC", cursive;
--font-body: "Nunito", sans-serif;
--font-hud: "Fredoka", "Pally", sans-serif;
--radius-chip: 15px;
--radius-panel: 12px;
--shadow-glow-neon: 0 0 8px #FFFCFF, 0 0 24px #553DFF, 0 0 64px rgba(65, 41, 234, 0.5);
--shadow-glow-amber: 0 0 16px #FFA201, 0 0 48px rgba(255, 162, 1, 0.4);
--spacing-base: 4px;
--spacing-xs: 8px;
--spacing-sm: 12px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-edge: 40px;
}{
"colors": {
"primary": "#553DFF",
"secondary": "#FFA201",
"background": "#1E0B43",
"background-deep": "#1D063B",
"surface": "#2A1155",
"neon-core": "#FFFCFF",
"grid-cross": "#4129EA",
"tree": "#6D54D3",
"floor-glow": "#6C4EB2",
"magenta": "#4118B4",
"lamp-bright": "#FFFF91",
"truck-light": "#FFFB94",
"text-primary": "#FFFFFF",
"text-faded": "rgba(255, 255, 255, 0.8)",
"danger": "#FF6A7C",
"danger-soft": "#FF87A2",
"success": "#D5FF95",
"warning": "#FFA201",
"info": "#6D54D3"
},
"typography": {
"display-hand": {
"fontFamily": "Amatic SC",
"fontSize": "64px",
"fontWeight": 700,
"note": "botones-letrero del mundo: Interact / Unstuck (real)"
},
"whisper": {
"fontFamily": "Amatic SC",
"fontSize": "50px",
"fontWeight": 700,
"note": "mensajes de visitantes (real)"
},
"title": {
"fontFamily": "Amatic SC",
"fontSize": "40px",
"fontWeight": 700,
"note": "titulos de panel (real); minimo absoluto de la familia"
},
"body": {
"fontFamily": "Nunito",
"fontSize": "20px",
"fontWeight": 400,
"note": "el font-size del body entero (real)"
},
"body-sm": {
"fontFamily": "Nunito",
"fontSize": "16px",
"fontWeight": 400
},
"label": {
"fontFamily": "Nunito",
"fontSize": "13px",
"fontWeight": 700,
"note": "chips del HUD (real)"
},
"hud": {
"fontFamily": "Pally",
"substitute": "Fredoka",
"fontSize": "20px",
"fontWeight": 500
}
},
"rounded": {
"chip": "15px",
"panel": "12px",
"letrero": "0",
"ring": "100%"
},
"shadow": {
"none": "none",
"glow-neon": "0 0 8px #FFFCFF, 0 0 24px #553DFF, 0 0 64px rgba(65, 41, 234, 0.5)",
"glow-amber": "0 0 16px #FFA201, 0 0 48px rgba(255, 162, 1, 0.4)"
},
"spacing": {
"base": "4px",
"xs": "8px",
"sm": "12px",
"md": "16px",
"lg": "24px",
"edge": "40px"
},
"motion": {
"ease-bounce": "cubic-bezier(0.34, 1.56, 0.64, 1)",
"ease-follow": "cubic-bezier(0.25, 0.1, 0.25, 1)",
"duration-pop": "350ms",
"duration-panel": "450ms",
"duration-pulse": "1600ms",
"driving": "simulación continua: masas, fuerzas y amortiguación, sin duración"
}
}---
version: "1.0"
name: "Bruno Simon"
description: "Sistema visual del portfolio de Bruno Simon: un videojuego conducible hecho en Three.js donde el visitante recorre el CV en un camión 4x4 sobre un suelo violeta profundo (#1E0B43) cuadriculado con cruces neón. La paleta es noche arcade: violeta eléctrico #553DFF para el neón y la vegetación, ámbar #FFA201 para las farolas y las luces del camión, blanco caliente #FFFCFF para los aros de neón, y acentos UI en rosa #FF6A7C (peligro) y lima #D5FF95 (WebGPU/éxito). Tipografía de juguete: Amatic SC condensada a mano para los rótulos gigantes, Nunito redonda para la conversación, y Pally (sustituida por Fredoka) para el HUD. Todo es físico: chocar, derrapar, romper. Dark mode juguetón, neón, con física real."
colors:
primary: "#553DFF"
secondary: "#FFA201"
canvas: "#1E0B43"
ink: "#FFFFFF"
neon-core: "#FFFCFF"
neon-violet: "#5D3CF4"
grid-cross: "#4129EA"
tree-highlight: "#6D54D3"
floor-glow: "#6C4EB2"
magenta-deep: "#4118B4"
lamp-bright: "#FFFF91"
truck-light: "#FFFB94"
background: "#1E0B43"
surface: "#2A1155"
surface-deep: "#1D063B"
text-primary: "#FFFFFF"
text-faded: "#FFFFFFCC"
danger: "#FF6A7C"
danger-soft: "#FF87A2"
success: "#D5FF95"
warning: "#FFA201"
info: "#6D54D3"
typography:
display-hand:
fontFamily: "Amatic SC"
fontSize: "64px"
fontWeight: 700
lineHeight: "normal"
letterSpacing: "normal"
whisper:
fontFamily: "Amatic SC"
fontSize: "50px"
fontWeight: 700
lineHeight: "normal"
letterSpacing: "normal"
title:
fontFamily: "Amatic SC"
fontSize: "40px"
fontWeight: 700
lineHeight: "normal"
letterSpacing: "normal"
body:
fontFamily: "Nunito"
fontSize: "20px"
fontWeight: 400
lineHeight: "normal"
letterSpacing: "normal"
body-sm:
fontFamily: "Nunito"
fontSize: "16px"
fontWeight: 400
lineHeight: "normal"
letterSpacing: "normal"
label:
fontFamily: "Nunito"
fontSize: "13px"
fontWeight: 700
lineHeight: "normal"
letterSpacing: "normal"
hud:
fontFamily: "Pally"
fontSize: "20px"
fontWeight: 500
lineHeight: "normal"
letterSpacing: "normal"
rounded:
chip: "15px"
panel: "12px"
ring: "100%"
spacing:
base: "4px"
xs: "8px"
sm: "12px"
md: "16px"
lg: "24px"
xl: "40px"
components:
button-game:
backgroundColor: "transparent"
textColor: "{colors.text-primary}"
typography: "{typography.display-hand}"
rounded: "0"
note: "Interact / Unstuck: rotulos Amatic SC 64px sin superficie, como letreros del mundo"
panel:
backgroundColor: "{colors.surface}"
textColor: "{colors.text-primary}"
typography: "{typography.body}"
rounded: "{rounded.panel}"
padding: "24px"
icon-chip:
backgroundColor: "{colors.surface-deep}"
textColor: "{colors.text-primary}"
typography: "{typography.label}"
rounded: "{rounded.chip}"
padding: "8px 12px"
start-ring:
borderColor: "{colors.neon-core}"
rounded: "{rounded.ring}"
glow: "0 0 24px {colors.neon-violet}, 0 0 64px {colors.grid-cross}"
whisper-input:
backgroundColor: "transparent"
textColor: "{colors.text-primary}"
typography: "{typography.whisper}"
placeholder: "Your message here"
---
# DESIGN.md - Bruno Simon
> Sistema de diseño extraído de `https://bruno-simon.com` (home, julio 2026) siguiendo el skill `url-inspiration-styleguide`.
> Colores, familias, tamaños y radios medidos sobre el sitio en vivo con Puppeteer: `@font-face` reales, estilos computados del HUD DOM y muestreo de píxeles de la captura 1600x900 (la escena es un render Three.js; el suelo, el neón y las luces no existen en CSS, así que se muestrean de la captura). Lo que el sitio no expone (escalas, estados con superficie) va marcado como *(derivado para completar el sistema)*.
---
## 1. Tema Visual y Atmósfera
El portfolio de Bruno Simon no se lee: **se conduce**. Al entrar hay un camión 4x4 aparcado bajo una farola, un aro de neón blanco que dice por dónde empezar y un rótulo escrito a mano: *CLICK TO START*. A partir de ahí, el visitante recorre el CV con las flechas del teclado (o un gamepad, o los pulgares en el móvil), derrapando entre secciones, atropellando bolos y dejando mensajes pintados en el suelo. Fue Site of the Year en Awwwards en su primera versión y sigue siendo el ejemplo canónico de "portfolio como videojuego"; la versión actual renderiza con WebGPU cuando el navegador puede (con toggle de calidad `High` visible en el HUD) y cae a WebGL cuando no.
El mundo es **noche arcade**. El suelo es un violeta profundo `#1E0B43` que se oscurece a `#1D063B` en los bordes del frame, cuadriculado con líneas y cruces de neón azul-violeta `#4129EA` que se pierden en perspectiva isométrica. La vegetación no es verde: los árboles son nubes de partículas violeta `#5C3CFF` con luces `#6D54D3`, como cerezos radiactivos. Las esquinas del frame viran a un magenta profundo `#4118B4`: la escena entera está iluminada como un local de recreativas.
Contra ese frío violeta, el sistema enciende **calor puntual**: la farola derrama un cono ámbar `#FFA201` que satura a `#FFFF91` en el foco; el camión lleva una barra LED naranja incandescente y luces de techo `#FFFB94`. La regla de color del mundo es exactamente esa: **violeta para el espacio, ámbar para la vida**. Y flotando entre ambos, el blanco caliente `#FFFCFF` del aro de neón, que no es un borde CSS sino un tubo de luz con bloom real.
La tipografía es de juguete y son tres voces medidas en el DOM: **Amatic SC** (la condensada manuscrita de Google) en 700 para todos los rótulos del mundo, gigante (40px los títulos de panel, 50px los mensajes de visitantes, 64px los botones `Interact` y `Unstuck`, que no tienen fondo ni borde: son letreros, no botones). **Nunito** en 400 para la conversación ("My name is Bruno Simon... Please drive around... And don't break anything!") a 20px redondos y amables. Y **Pally** (Fontshare, peso 500) para piezas del HUD. Los acentos de interfaz son caramelo: rosa `#FF6A7C` para los avisos ("Server currently offline"), lima `#D5FF95` para la insignia WebGPU.
**Palabras clave de personalidad**: juguetón, arcade, neón, físico, conducible, nocturno, manuscrito, cálido en los focos
**Densidad del layout**: el HUD es mínimo (contador, mapa, sonido, calidad); el mundo es denso en objetos con física
**Modo preferido**: oscuro violeta (la escena es de noche; no existe modo claro)
**Nivel de ornamentación**: alto y funcional: cada adorno (bolos, farolas, vallas) es un objeto con física que se puede chocar
**Audiencia visual objetivo**: developers creativos y clientes que quieren ver hasta dónde llega Three.js; visitantes que se quedan a jugar
---
## 2. Paleta de Colores y Roles Semánticos
Una noche violeta con dos temperaturas: neón frío para el espacio (violetas, magentas, azul eléctrico) y focos cálidos para la vida (ámbar, amarillo). Los acentos de UI son pastel caramelo (rosa, lima) medidos directamente del DOM.
### Colores de marca
| Nombre | Variable CSS | Hex | Rol | Texto sobre él |
|--------|-------------|-----|-----|----------------|
| Violeta neón | `--color-primary` | `#553DFF` | El neón del mundo: aro (saturación medida `#5D3CF4`-`#553DFF`), árboles `#5C3CFF`, cruces del suelo | `#FFFFFF` |
| Ámbar farola | `--color-secondary` | `#FFA201` | El calor: farolas, luces del camión, foco de atención | `#1E0B43` |
| Violeta suelo | `--color-canvas` | `#1E0B43` | El terreno del mundo entero (medido en captura) | `#FFFFFF` |
| Neón blanco | `--color-neon-core` | `#FFFCFF` | El núcleo del tubo de neón del aro de inicio | no lleva texto |
### Colores de escena (muestreados de la captura 1600x900)
La escena es un render Three.js: estos valores están muestreados píxel a píxel, no declarados en CSS.
| Nombre | Hex | Dónde se midió |
|--------|-----|----------------|
| Suelo | `#1E0B43` | Terreno medio (cuantizado dominante `#200040`, 23.9% del frame) |
| Suelo profundo | `#1D063B` | Bordes inferiores del frame |
| Cruz de rejilla | `#4129EA` | Las marcas `x` del suelo (pico de saturación `#422ADF`) |
| Aro de neón | `#553DFF` a `#FFFCFF` | Tubo: violeta en el halo, blanco caliente en el núcleo |
| Árbol violeta | `#5C3CFF` / `#6D54D3` | Copas de partículas y sus luces |
| Halo del suelo | `#6C4EB2` | El interior iluminado del aro de inicio |
| Magenta esquina | `#4118B4` | Viñeteo magenta de las esquinas superiores |
| Farola | `#FFA201` a `#FFFF91` | Cono de luz y foco |
| Luces del camión | `#FFFB94` | Barra LED y techo |
### Colores de superficie
| Nombre | Variable CSS | Hex | Rol |
|--------|-------------|-----|-----|
| Canvas | `--color-background` | `#1E0B43` | El suelo del mundo; el fondo de cualquier UI |
| Superficie | `--color-surface` | `#2A1155` | Paneles sobre el mundo *(derivado: el suelo iluminado un paso)* |
| Superficie honda | `--color-surface-deep` | `#1D063B` | Zonas de reposo, footers *(medido en bordes)* |
### Colores de texto
| Nombre | Variable CSS | Hex | Uso |
|--------|-------------|-----|-----|
| Blanco | `--color-text-primary` | `#FFFFFF` | Todo el texto del sitio (real: títulos, body, botones) |
| Blanco desvanecido | `--color-text-faded` | `rgba(255,255,255,0.8)` | Metadata del HUD (real: labels de calidad) |
| Rosa peligro | `--color-danger` | `#FF6A7C` | Estado offline del HUD (real: `rgb(255,106,124)`) |
| Rosa aviso | `--color-danger-soft` | `#FF87A2` | Mensajes de error largos (real: `rgb(255,135,162)`) |
| Lima | `--color-success` | `#D5FF95` | Insignia WebGPU del HUD (real: `rgb(213,255,149)`) |
### Contraste verificado (sobre `#1E0B43`)
| Combinación | Ratio | Nivel |
|-------------|-------|-------|
| `#FFFFFF` sobre `#1E0B43` | 17.7:1 | AAA |
| `#D5FF95` sobre `#1E0B43` | 15.7:1 | AAA |
| `#FFFF91` sobre `#1E0B43` | 16.2:1 | AAA |
| `#FFA201` sobre `#1E0B43` | 8.8:1 | AAA |
| `#FF6A7C` sobre `#1E0B43` | 6.4:1 | AA (AAA en texto grande) |
| `#FF87A2` sobre `#1E0B43` | 8.1:1 | AAA |
| `#6D54D3` sobre `#1E0B43` | 3.6:1 | solo texto grande o decorativo |
| `#553DFF` sobre `#1E0B43` | 3.0:1 | solo display/neón, nunca texto pequeño |
| `#1E0B43` sobre `#FFA201` | 8.8:1 | AAA |
> **La trampa del neón**: el violeta `#553DFF` brilla muchísimo en pantalla pero solo rinde 3:1 sobre el suelo. En el sitio real nunca es texto: es tubo, árbol y rejilla. Si lo necesitas como texto, súbelo a `#6D54D3`+tamaño grande o pásalo a blanco con glow violeta.
### Colores de estado
Los tres primeros son reales (medidos en el DOM del HUD); el resto *(derivado para completar el sistema)*.
| Estado | Variable CSS | Hex | Origen |
|--------|-------------|-----|--------|
| Peligro | `--color-danger` | `#FF6A7C` | Real: "Offline" del HUD |
| Peligro suave | `--color-danger-soft` | `#FF87A2` | Real: "Server currently offline. Scores can't be saved." |
| Éxito / capacidad | `--color-success` | `#D5FF95` | Real: insignia "WebGPU" |
| Aviso | `--color-warning` | `#FFA201` | El ámbar de las farolas *(rol derivado)* |
| Info | `--color-info` | `#6D54D3` | El violeta claro de los árboles *(rol derivado)* |
---
## 3. Reglas de Tipografía
```css
/* Tres familias reales medidas en el DOM:
1. Amatic SC 700 (Google Fonts, directa): rótulos del mundo
2. Nunito 400/700/900 (Google Fonts, directa): conversación y HUD
3. Pally 400/500/700 (Fontshare, self-hosted) -> sustituto Google: Fredoka */
--font-display: 'Amatic SC', cursive;
--font-body: 'Nunito', sans-serif;
--font-hud: 'Fredoka', 'Pally', sans-serif;
--font-mono: ui-monospace, SFMono-Regular, Menlo, monospace; /* no detectada en el sitio (derivada para código) */
```
**Google Fonts:**
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Amatic+SC:wght@700&family=Nunito:wght@400;700;900&family=Fredoka:wght@400;500;700&display=swap" rel="stylesheet">
```
### Nota sobre sustitución tipográfica
**Amatic SC y Nunito son Google Fonts y se usan directas, sin sustitución** (caso poco común en esta galería: dos de las tres fuentes reales del sitio son libres).
**Original: Pally -> HTML: Fredoka (Google substitute).** Pally (Indian Type Foundry, distribución Fontshare) es una geométrica redonda y regordeta con terminales blandos y personalidad de juguete, cargada por el sitio en Regular/Medium/Bold para piezas del HUD. Fontshare no es Google Fonts y su licencia ITF no permite redistribución casual.
Candidatas comparadas antes de decidir:
| Candidata | Por qué encaja | Por qué se descarta |
|---|---|---|
| **Fredoka** | Geométrica redonda con la misma jovialidad regordeta, terminales blandos y contadores generosos; pesos 300-700 con los tres que Pally aporta (400/500/700). A tamaños de HUD (13-20px) es casi intercambiable. | **Elegida.** |
| Baloo 2 | Muy cercana en espíritu rechoncho. | Más pesada de color tipográfico en 400: a 13px del HUD empasta contra el neón. |
| Quicksand | Geométrica redonda ligera. | Demasiado esbelta y elegante: pierde el "juguete" que comparten Pally y el mundo del sitio. |
| Comfortaa | Redondez máxima. | Su geometría es tan protagonista que compite con Amatic SC; el HUD debe ser neutro-amable. |
### Escala tipográfica
> Tamaños reales medidos: **64px** (botones Interact/Unstuck, Amatic 700), **50px** (whispers, Amatic 700), **40px** (títulos de panel, Amatic 700), **20px** (body Nunito 400, el `font-size` del body entero), **16px** (notas `text-small`), **13px** (labels 700 del HUD).
| Token | px real | Weight | Familia | Uso |
|-------|---------|--------|---------|-----|
| `--f-display-hand` | 64px | 700 | Amatic SC | Botones-letrero del mundo (`Interact`, `Unstuck`) |
| `--f-whisper` | 50px | 700 | Amatic SC | Mensajes de visitantes ("Your message here") |
| `--f-title` | 40px | 700 | Amatic SC | Títulos de panel (`Three.js`, `Devlogs`, `Musics`) |
| `--f-body` | 20px | 400 | Nunito | Conversación y párrafos (el default del body) |
| `--f-body-sm` | 16px | 400 | Nunito | Notas y aclaraciones (`text-small text-faded`) |
| `--f-label` | 13px | 700 | Nunito | Labels de iconos del HUD ("Mouse Keyboard", "Mobile Tablet") |
| `--f-hud` | 20px | 500 | Pally/Fredoka | Piezas de HUD con voz propia |
### Pesos tipográficos
```css
/* Amatic SC: solo 700. A 40-64px el trazo manuscrito necesita el bold. */
--font-hand: 700;
/* Nunito: 400 el body, 700 los labels, 900 cargada para énfasis puntual. */
--font-regular: 400;
--font-bold: 700;
--font-black: 900;
/* Pally: 500 (Medium) como peso de trabajo del HUD. */
--font-hud-weight: 500;
```
### Reglas de composición
- **Amatic SC nunca baja de 40px.** Es una condensada manuscrita: a tamaños de párrafo se vuelve ilegible. En el sitio real su mínimo medido es 40px.
- **Nunito nunca hace de display.** A 20px/400 es la voz que explica; los titulares son siempre de Amatic.
- **Sin tracking en ninguna de las tres.** Todo va con `letter-spacing: normal` (medido). La personalidad ya la ponen los esqueletos.
- **line-height normal.** El sitio no fuerza interlíneas: los rótulos manuscritos respiran con su métrica nativa.
---
## 4. Estilos de Componentes
### Botón-letrero (componente firma)
Los "botones" del mundo (`Interact`, `Unstuck`) no tienen caja: son rótulos manuscritos gigantes, como letreros pintados que flotan sobre la escena.
```
Background: transparent (real)
Border: none (real)
Border-radius: 0 (real)
Font: Amatic SC 700, 64px (real)
Color: #FFFFFF (real)
Sombra de texto: 0 0 12px rgba(85,61,255,0.6) (derivado: glow neón para despegarlo del suelo)
Hover (derivado del comportamiento del mundo):
Transform: scale(1.06) con rebote
El glow sube de radio
Regla: si un control vive DENTRO del mundo, no lleva superficie.
Las cajas son para paneles que interrumpen el juego.
```
### Rótulo manuscrito de instrucción
```
"CLICK TO START" con flecha dibujada a mano apuntando al aro
Font: Amatic SC 700, blanco #FFFFFF
Acompañado de icono de sonido dibujado con el mismo trazo
Regla: las instrucciones son parte del decorado, no tooltips
```
### Aro de inicio (neón)
```
Forma: elipse en perspectiva sobre el suelo
Tubo: núcleo #FFFCFF de 2-3px + halo #553DFF
Glow: bloom real en la escena; en CSS plano (derivado):
box-shadow: 0 0 8px #FFFCFF, 0 0 24px #553DFF, 0 0 64px #4129EA
Interior: el suelo se ilumina a #6C4EB2
Rol: zona de acción. El neón marca "aquí pasa algo".
```
### Panel de contenido
Los paneles (whispers, menú, leaderboard) interrumpen el juego con una capa.
```
Background: rgba(30,11,67,0.92) (derivado del suelo #1E0B43)
Border-radius: 12px (derivado; el DOM real usa overlay a sangre)
Padding: 24px
Título: Amatic SC 700, 40px, #FFFFFF (real)
Body: Nunito 400, 20px, #FFFFFF (real)
Nota: Nunito 400, 16px, rgba(255,255,255,0.8) (real: text-small text-faded)
Línea divisoria: 1px #FFFFFF (real: div.line con background blanco)
```
### Chip de icono del HUD
```
Contenido: icono + label ("Mouse Keyboard", "Mobile Tablet", mando Xbox)
Label: Nunito 700, 13px, #FFFFFF (real)
Icono de gamepad: radio 15px (real: span.icon.is-xbox)
Background: transparente sobre el mundo; superficie #1D063B si necesita asiento (derivado)
```
### Insignias de estado del HUD (reales)
```
Calidad: "High" - Nunito 400, 20px, rgba(255,255,255,0.8), line-height 58px
Motor: "WebGPU" - Nunito 400, 20px, #D5FF95 (lima)
Servidor: "Offline" - Nunito 400, 20px, #FF6A7C (rosa)
Regla: el estado técnico se muestra con orgullo en el HUD, con color
de caramelo: la insignia WebGPU en lima es parte de la marca.
```
### Whisper (mensaje de visitante)
```
Input y render: Amatic SC 700, 50px, #FFFFFF (real)
Placeholder: "Your message here"
Reglas mostradas al usuario (reales): "Everyone can see them" + notas en 16px faded
En el mundo: el mensaje queda pintado en el suelo con el mismo trazo
```
### Contador / cronómetro
```
Uso: vueltas cronometradas y récords ("Resets in...")
Font: Nunito 400, 20px (real); cifras grandes en Amatic 700 (derivado)
Aviso de servidor: #FF87A2 (real)
```
### Triggers del HUD (menú y mapa)
```
Botones reales: js-menu-trigger y js-map-trigger (Nunito 400, 20px)
Sin caja: iconos dibujados sobre el mundo, anclados a las esquinas
Hover: scale con rebote (derivado de la voz del mundo)
```
### Navegación de paneles
```
Botones reales del DOM: previous / next / open / close
Font heredada: Amatic SC 700, 64px (misma voz que los letreros)
Las flechas de navegación son rótulos, no iconos de sistema
Cierre: botón js-close con label de teclado ("A" para gamepad)
```
---
## 5. Principios de Layout
### El layout es un mundo con HUD
No hay grid de página: hay una escena isométrica-cenital y capas de HUD ancladas a los bordes. La cámara sigue al camión; el "layout" es la composición del encuadre.
```
+--------------------------------------------------+
| [sonido] [calidad High/WebGPU] [mapa] |
| |
| (mundo: camión, farola, |
| aro de neón, árboles) |
| |
| CLICK TO START ~~~> (rótulo en escena) |
| |
| [chips de input: teclado/touch/gamepad] [menú] |
+--------------------------------------------------+
```
### Escala de espaciado
*(derivada: el DOM real ancla por absolutos; base 4px coherente con los paddings observados)*
```css
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 24px;
--space-6: 40px; /* margen del HUD a los bordes */
```
### Reglas
1. **El centro es del juego.** El HUD nunca invade el tercio central del frame, donde vive el camión.
2. **Las instrucciones se rotulan en el mundo** (CLICK TO START junto al aro), no en overlays.
3. **Cada objeto es interactivo o no existe.** Bolos, vallas y letras del suelo tienen cuerpo físico: el decorado es jugable.
4. **Los paneles pausan.** Cuando un panel de contenido abre, el mundo queda detrás desenfocado/oscurecido y el input pasa al panel.
---
## 6. Profundidad y Elevación
La profundidad se hace con **luz de neón y bloom**, no con sombras CSS (medido: `box-shadow: none` en todo el DOM).
### Sistema de elevación
| Nivel | Técnica | Uso |
|-------|---------|-----|
| 0 - Suelo | `#1E0B43` con viñeteo a `#1D063B` y magenta `#4118B4` en esquinas | El mundo |
| 1 - Rejilla | Cruces `#4129EA` con leve emisión | La textura del suelo |
| 2 - Objeto | Iluminación de escena + sombras proyectadas del render | Camión, árboles, farola |
| 3 - Neón | Tubo `#FFFCFF` + halo `#553DFF` + suelo iluminado `#6C4EB2` | Zonas de acción |
| 4 - Foco | Conos ámbar `#FFA201` -> `#FFFF91` | Los puntos de vida |
| 5 - HUD/Panel | Blanco sobre overlay oscuro, sin sombra | La interfaz |
```css
/* Glow de neón para CSS plano (derivado de los valores medidos) */
--glow-neon: 0 0 8px #FFFCFF, 0 0 24px #553DFF, 0 0 64px rgba(65, 41, 234, 0.5);
--glow-amber: 0 0 16px #FFA201, 0 0 48px rgba(255, 162, 1, 0.4);
--shadow-none: none; /* el DOM real no usa box-shadow */
```
> **Regla**: lo que importa emite luz; lo que descansa la recibe. Un elemento "elevado" en este sistema no flota con sombra: **brilla**. El violeta ilumina espacio, el ámbar ilumina vida.
### Radios de borde
```css
--radius-chip: 15px; /* real: el icono de gamepad del HUD */
--radius-panel: 12px; /* derivado para paneles */
--radius-ring: 100%; /* el aro de neón */
--radius-letrero: 0; /* real: los botones-letrero no tienen caja */
```
---
## 7. Lo que Sí y lo que No
### Sí hacer
1. **Violeta para el espacio, ámbar para la vida.** El mundo entero es frío `#1E0B43`/`#553DFF`; el calor `#FFA201` se reserva para faros, farolas y focos de atención.
2. **Rotula en Amatic SC 700 y nunca por debajo de 40px.** Los títulos de este sistema son letreros de mano gigantes.
3. **Explica en Nunito 400 a 20px.** Amable, redonda, sin tracking. La diferencia entre rotular y conversar es la firma tipográfica.
4. **Haz que la elevación brille**: neón blanco con halo violeta para zonas de acción, glow ámbar para lo vivo. Nada de sombras negras.
5. **Deja los controles del mundo sin caja** (letreros transparentes); reserva las superficies para paneles que pausan el juego.
6. **Muestra el estado técnico con orgullo y color caramelo**: WebGPU en lima `#D5FF95`, offline en rosa `#FF6A7C`.
7. **Da cuerpo físico a la decoración.** Si algo está en el mundo, se puede chocar. La interactividad es la ornamentación.
8. **Marca las zonas de acción con un aro de neón en el suelo**, no con un botón flotante.
### No hacer
1. **No uses el violeta neón `#553DFF` como texto pequeño.** Rinde 3:1 sobre el suelo: es tubo y rejilla, no tipografía.
2. **No pongas Amatic SC en párrafos.** Por debajo de 40px la manuscrita condensada se rompe.
3. **No enfríes el ámbar.** Las farolas son `#FFA201` puro; un amarillo pastel apaga los focos de vida del mundo.
4. **No uses sombras negras CSS.** La profundidad aquí es luz (bloom, halos, conos); una `box-shadow` gris rompe la noche arcade.
5. **No conviertas los letreros en botones con caja.** `Interact` a 64px transparente es la voz del mundo; una píldora con fondo lo convierte en un formulario.
6. **No añadas tracking ni caps forzadas.** Todo el sistema va con `letter-spacing: normal` y la caja que trae cada familia.
7. **No pongas verde natural en la vegetación.** Los árboles de este mundo son violeta `#5C3CFF`: el color es de neón, no de bosque.
8. **No tapes el tercio central del frame con HUD.** Ahí vive el camión; la interfaz respeta el juego.
---
## 8. Comportamiento Responsive
### Breakpoints
El sitio no reordena columnas: **cambia el esquema de control y el encuadre**.
```css
/* (derivado del comportamiento observable y de los chips de input reales) */
/* sm: */ @media (min-width: 640px) { }
/* md: */ @media (min-width: 768px) { }
/* lg: */ @media (min-width: 1024px) { }
```
### Cambios por breakpoint
**Mobile (< 640px)**
- Input: joystick táctil + botones `Interact`/`Unstuck` en pantalla (reales: `js-touch-buttons`)
- La cámara encuadra más cerca del camión
- Los paneles de contenido pasan a sangre completa
- El HUD reduce a sonido + mapa; las insignias de calidad se ocultan
**Tablet (640px a 1024px)**
- Controles táctiles con chips de icono visibles ("Mobile Tablet", real)
- Calidad de render ajustada (menos partículas de vegetación)
**Desktop (> 1024px)**
- Teclado (WASD/flechas) y gamepad (chips con iconos Xbox reales en el DOM)
- Encuadre amplio con el viñeteo magenta completo
- Insignias High/WebGPU visibles
### Touch y accesibilidad de juego
- Botones táctiles de gran superficie (los letreros de 64px son el target)
- `Unstuck` siempre visible: la mecánica de rescate es parte de la UI (si el camión vuelca, un botón lo endereza)
- El sitio detecta el esquema de entrada y muestra chips explicativos con icono + label de 13px/700
---
## 9. Guía de Prompts para Agentes
### Prompt de inicialización de sesión
```text
Estás trabajando con el sistema de diseño del portfolio de Bruno Simon
(videojuego conducible en Three.js).
PALETA: suelo violeta profundo #1E0B43 (bordes #1D063B, esquinas magenta
#4118B4). Neón violeta #553DFF para espacio: aro de inicio (núcleo blanco
caliente #FFFCFF), árboles #5C3CFF/#6D54D3, cruces de rejilla #4129EA.
Calor SOLO en focos de vida: ámbar #FFA201 (farolas, luces del camión,
picos #FFFF91). UI caramelo: peligro rosa #FF6A7C/#FF87A2, éxito lima
#D5FF95. Texto siempre blanco #FFFFFF (faded: 80%).
TIPOGRAFÍA: Amatic SC 700 para rótulos (40px mínimo, 50-64px normal),
Nunito 400 para conversación (20px) y 700 para labels (13px), Fredoka
(sustituta de Pally) para HUD. Sin tracking, line-height normal.
ESTILO: los controles del mundo son letreros transparentes sin caja;
las superficies son para paneles que pausan. Elevación = luz (glow neón
violeta, glow ámbar), nunca box-shadow negra. Radios: 15px chips, 12px
paneles, 0 letreros. MODO: noche arcade, sin modo claro.
```
### Prompt: Crear nueva pantalla
```text
Crea una pantalla de [FUNCIONALIDAD] para el mundo de Bruno Simon.
Requisitos:
- Fondo violeta #1E0B43 con viñeteo #1D063B y esquinas magenta
- Titular en Amatic SC 700 a 40px o más, blanco
- Body en Nunito 400 a 20px, blanco; notas a 16px al 80%
- La acción principal marcada con neón: aro/subrayado #FFFCFF + halo #553DFF
- Un solo foco ámbar #FFA201 por vista (la vida de la escena)
- Controles del mundo sin caja (letrero transparente + glow); paneles
con superficie rgba(30,11,67,0.92) y radio 12px
- Estados con color caramelo: rosa #FF6A7C peligro, lima #D5FF95 éxito
- Nada de sombras negras: la profundidad es luz
```
### Prompt: Añadir componente al UI kit
```text
Añade un componente de [TIPO] al sistema de Bruno Simon.
Debe:
- Usar solo tokens del DESIGN.md de Bruno Simon
- Elegir voz: letrero del mundo (Amatic 700 >= 40px, transparente, glow)
o panel (superficie violeta, radio 12px, Nunito)
- Estados: hover con scale(1.06) y rebote; focus con aro de neón
(outline #FFFCFF + halo violeta); disabled al 40%
- Peligro en rosa #FF6A7C, éxito en lima #D5FF95, foco de atención
en ámbar #FFA201
- Sin box-shadow negra; el glow es la elevación
```
### Prompt: Revisión de consistencia
```text
Revisa esta interfaz y detecta qué no sigue el sistema de Bruno Simon.
Verifica:
1. Si Amatic SC aparece por debajo de 40px (no debe)
2. Si el violeta neón #553DFF se usa como texto pequeño (no debe: 3:1)
3. Si hay box-shadow negra donde debería haber glow
4. Si el ámbar #FFA201 se reparte en vez de concentrarse en focos de vida
5. Si los controles del mundo llevan caja/fondo (deben ser letreros)
6. Si hay tracking o caps forzadas (todo va normal)
7. Si la vegetación u objetos del mundo usan colores naturales (aquí son neón)
8. Si el HUD invade el tercio central del frame
9. Si los estados usan rojo/verde de sistema en vez del caramelo rosa/lima
```
### Prompt: Variante de campaña
```text
Genera una variante [sección del mundo / minijuego / evento] para
Bruno Simon manteniendo el sistema base.
Conserva:
- El suelo violeta #1E0B43 con rejilla de cruces #4129EA
- Amatic SC 700 gigante para rótulos y Nunito 400 para conversación
- La regla de temperatura: violeta = espacio, ámbar = vida
- El neón blanco/violeta como marcador de zonas de acción
Puedes variar:
- Los objetos físicos de la zona (bolos, rampas, dianas)
- El color del neón de zona (lima #D5FF95 para retos, rosa #FF6A7C
para peligro), manteniendo el núcleo blanco del tubo
- La densidad de vegetación violeta
```
---
## 10. Movimiento (Motion) e Interacción JS
El motion de este sitio no es animación de interfaz: **es un motor de físicas al servicio del humor**. El portfolio fue Site of the Year en Awwwards precisamente por esto: la interacción ES el contenido. Es el motivo por el que está en esta galería.
**Nivel de motion**: total. Todo lo que se ve tiene simulación: el camión tiene suspensión, los bolos caen, las letras del suelo salen despedidas.
**Arquitectura observada**:
- Canvas Three.js a viewport completo (`js-canvas experience`, 1600x900 a dpr 1)
- **Renderer WebGPU con fallback**: el HUD real muestra las insignias `High` y `WebGPU` (lima `#D5FF95`); la calidad es configurable
- Física de vehículo: chasis + 4 ruedas con suspensión, derrape y vuelco (de ahí el botón real `Unstuck`)
- Multi-input real: teclado, touch (joystick + botones `js-touch-buttons`) y gamepad (chips con iconos Xbox en el DOM)
- Sistema social ("whispers"): mensajes de visitantes escritos en Amatic 50px que quedan en el mundo; leaderboard con servidor (el HUD real avisa "Server currently offline. Scores can't be saved." en rosa y "Resets in..." para el reinicio de récords)
**Patrones de motion observados**:
- **Conducción física**: aceleración, frenada, derrape con inercia; la cámara cenital sigue al camión con lag suave (lerp) para que el mundo "gire" alrededor
- **Loader jugable**: la pantalla de carga termina en un rótulo manuscrito CLICK TO START con flecha dibujada; el clic inicial también desbloquea el audio
- **Objetos rompibles**: bolos, vallas y letras con cuerpo físico; chocar es la micro-interacción principal ("And don't break anything!" es la instrucción real del intro)
- **Neón como señal**: las zonas de acción laten con bloom; el aro de inicio es un tubo de luz, no un borde
- **Botón-letrero con rebote**: `Interact`/`Unstuck` aparecen contextualos, con entrada elástica *(comportamiento derivado de la voz del mundo)*
- **Sonido físico**: motor, colisiones y bocina ligados a la simulación; toggle de sonido en el HUD desde el primer frame
**Duraciones y easings** *(la simulación no usa duraciones: usa masas, fuerzas y amortiguación; estos valores son la traducción derivada a CSS)*:
```css
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1); /* entradas de letreros: rebote */
--ease-follow: cubic-bezier(0.25, 0.1, 0.25, 1); /* cámara: lag suave */
--duration-pop: 350ms; /* aparición de letreros y chips */
--duration-panel: 450ms; /* apertura de paneles de contenido */
--duration-pulse: 1600ms; /* latido del neón de zonas de acción */
/* la conducción y las colisiones no tienen duración: son simulación continua */
```
**Inventario de interacciones observadas**:
| Interacción | Disparador | Respuesta | Capa |
|-------------|-----------|-----------|------|
| Conducción | teclado / touch / gamepad | física de vehículo con suspensión | render |
| Colisión | contacto con objetos | los objetos salen despedidos + sonido | render |
| Vuelco | física | botón Unstuck aparece (64px Amatic) | render+DOM |
| Zona de acción | entrar en el aro de neón | el contenido se activa / panel abre | render+DOM |
| Whisper | escribir en el input (50px) | mensaje pintado en el suelo del mundo | DOM→render |
| Leaderboard | cruzar meta cronometrada | tiempo enviado al servidor ("Resets in") | DOM+red |
| Cambio de calidad | toggle High del HUD | densidad de render ajustada | DOM→render |
| Sonido | CLICK TO START inicial | audio desbloqueado; motor y bocina | DOM→audio |
| Mapa / menú | js-map-trigger / js-menu-trigger | overlay sobre el juego | DOM |
**Reglas de interacción**:
1. **El input es siempre físico**: no hay "click en card", hay conducir hasta la zona y entrar en el aro de neón.
2. **El error es divertido**: volcar el camión no es un fallo, es la razón de que exista el botón `Unstuck` (a 64px manuscritas).
3. **Lo social vive en el mundo**: los whispers no son un muro de comentarios, son pintadas en el suelo que el visitante atraviesa conduciendo.
4. **El estado técnico es celebración**: la insignia WebGPU en lima presume del motor; la calidad es un ajuste visible, no un menú oculto.
> **Accesibilidad**: respeta `@media (prefers-reduced-motion: reduce)`: cámara sin lag (seguimiento rígido), neón sin latido (brillo fijo), letreros sin rebote (aparición por opacidad). Los paneles de contenido (Three.js Journey, Devlogs, Source code, Musics: títulos H2 reales del DOM) ofrecen el contenido del portfolio en HTML navegable, con lo que el CV es legible sin conducir.
---
## Anexo: Stack técnico detectado
- **Plataforma**: escena Three.js a canvas completo (`js-canvas experience`) con **renderer WebGPU** y fallback (insignias reales `High` / `WebGPU` en el HUD); física de vehículo con suspensión y vuelco (botón `Unstuck` real).
- **Título real del documento**: "Bruno's".
- **Sistema de tokens**: cero variables CSS en el `:root`. El body declara `font-size: 20px` con `Nunito, sans-serif`; el fondo es transparente (la escena pinta el color).
- **Tipografía**: tres familias reales cargadas: **Amatic SC 700** (Google, `document.fonts`), **Nunito 400/700/900** (Google) y **Pally Regular/Medium/Bold** (`@font-face` self-hosted de Fontshare; Medium cargado en uso). Cargador de fuentes propio (`js-fonts-loader` con un div de prueba por familia).
- **Colores DOM reales**: texto `#FFFFFF` y `rgba(255,255,255,0.8)`; peligro `rgb(255,106,124)` y `rgb(255,135,162)`; lima WebGPU `rgb(213,255,149)`; divisor `div.line` blanco; icono gamepad con radio 15px.
- **Colores de escena muestreados** (captura 1600x900, cuantización 16): suelo dominante `#200040`-cluster (23.9% del frame), medido fino `#1E0B43`/`#1D063B`; neón `#553DFF`/`#5D3CF4` con núcleo `#FFFCFF`; cruces `#4129EA`; árboles `#5C3CFF`/`#6D54D3`; halo de suelo `#6C4EB2`; esquinas `#4118B4`; farola `#FFA201`->`#FFFF91`; luces del camión `#FFFB94`.
- **Input**: teclado, touch (`js-touch-buttons` con joystick) y gamepad (iconos Xbox reales: `span.icon.is-xbox`); chips explicativos "Mouse Keyboard" / "Mobile Tablet" a 13px/700.
- **Social/backend**: whispers (mensajes de visitantes, input Amatic 50px "Your message here", reglas visibles), leaderboard con reset programado ("Resets in") y aviso de estado del servidor en rosa.
- **Paneles de contenido**: títulos H2 reales `Three.js`, `Three.js Journey`, `Devlogs`, `Source code`, `Musics`, `Some more links` (Amatic 40px).
- **Reconocimiento**: Awwwards Site of the Year (primera versión, 2019); el portfolio conducible es referencia canónica de Three.js y del propio curso Three.js Journey de Bruno Simon.
- **(no detectado)**: framework de UI (DOM artesanal), librería de física expuesta (Cannon.js en v1 según el propio autor; la actual no la declara en el DOM), variables CSS de color, box-shadows (ninguna), modo claro, tipografía mono.