--- 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 ``` ### 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.