Portfolio PHP,
explicado en vivo.
Cada pieza interactiva del sitio —la lámpara de lava, el cursor, el sistema de modos— está reconstruida aquí mismo, junto al texto que la explica. Lo que lees es, en parte, lo que estás viendo.
Una sola plantilla, sin build step
El sitio es un portfolio de una sola plantilla PHP (index.php) más una página secundaria (contact.php), construido con includes de PHP para header, footer y config. Sin framework, sin paso de compilación: se abre directo en XAMPP y funciona.
Sobre esa base "normal" se apoya una capa de personalización visual: la lámpara de lava de fondo, el cursor a medida y el dock lateral de modos cosméticos —el mismo que tienes fijo a la izquierda de esta página.
Cómo se reparten las piezas
includes/
config.php → $site, $skills, $projects, $experience, $nav
header.php → head, fondo, overlays de modos, dock, header
footer.php → footer y carga de los scripts
pages/
contact.php → formulario de contacto
css/main.css → todo el CSS del sitio
js/
main.js → cursor, blobs, scroll-reveal, menú móvil
modes.js → todo el sistema de Modos
header.php y footer.php se incluyen desde cada página, así que $site, $skills y $projects están disponibles en todas partes sin repetir código.
Todo vive en arrays de PHP
No hay base de datos: $site, $skills, $projects, $experience y $nav son arrays que config.php expone al resto del sitio. Para añadir un proyecto nuevo basta con agregar un elemento más a $projects; el foreach en index.php genera la tarjeta automáticamente.
Siete variables, un sitio entero
Casi todos los colores pasan por variables CSS definidas en :root. Es la pieza clave que permite que "Cambiar color" y "Frutiger" retiñan el sitio completo sin tocar cada regla una por una.
| Variable | Uso |
|---|---|
--bg | fondo base |
--bg-3 | tarjetas e inputs |
--fg | texto principal |
--accent | color de acento |
--border | bordes translúcidos |
Diez manchas, cuatro pasos, un fundido
Diez <div class="blob"> fijos detrás de todo el contenido. Cada uno recibe al cargar un tamaño y posición aleatorios, una duración y delay propios, un tono aleatorio para su radial-gradient, y cuatro pares de variables de transformación que la animación interpola en cuatro pasos —moviendo, rotando y deformando el border-radius para simular un fluido orgánico.
Con mix-blend-mode: screen, donde dos manchas se superponen se funden en un brillo más intenso: el efecto clásico de lámpara de lava.
Un punto y un anillo con retraso
El cursor del sistema se oculta y se reemplaza por dos elementos: un punto que sigue al mouse 1:1, y un anillo que lo persigue con retraso, interpolado con lerp en cada frame. Al pasar sobre un enlace o botón, ambos crecen.
Un dock, cinco efectos, una sola regla
Todo vive en un IIFE dentro de modes.js, cargado después de main.js porque necesita que los blobs y el cursor ya existan en el DOM.
7.1 — El dock y su colapso
El panel empieza colapsado: solo se ve un punto pequeño con una pista pulsante ("¡Pruébalo!") invitando al clic. Un solo botón alterna una clase colapsado en el contenedor; el resto es transición CSS pura sobre max-width, max-height y opacity.
Ese dock es el que tienes fijo a la izquierda de esta página —abrelo si aún no lo hiciste.
7.2 — Modo Noche
Un overlay de pantalla completa con un radial-gradient negro que deja un agujero transparente centrado en la posición del mouse, actualizada en cada mousemove vía variables CSS --mx/--my.
Pruébalo desde el dock: verás el resto de la página oscurecerse salvo un círculo alrededor del cursor.
7.3 — Modo Enfoque
Mismo mecanismo de coordenadas, pero en vez de oscurecer, aplica backdrop-filter: blur() a todo lo de detrás y usa mask-image para que ese desenfoque no se aplique en un círculo alrededor del cursor.
7.4 — Modo Baldosas
Genera dinámicamente una grilla de baldosas opacas. Al hacer clic, cada baldosa calcula su distancia al punto y desaparece con un setTimeout proporcional a esa distancia —las más cercanas se revelan antes que las lejanas, dando un efecto de onda expansiva.
7.5 — Modo Frutiger
Frutiger Aero es la estética de ~2004–2013 —Windows Vista/7 Aero, el primer iPhone, la Wii— con botones de gel brillante, cielos celestes y burbujas. Aquí se implementa como un reskin completo por variables: al activarse, redefine --bg, --fg y --accent a una paleta de cielo, fuerza los blobs a border-radius: 50% (burbujas en vez de manchas), y añade burbujas ascendentes más bokeh y destello de lente.
Pruébalo desde el dock: toda la página —incluida esta sección— se retiñe sola, porque ya usaba las mismas variables.
7.6 — Cambiar color
Un ciclo de cinco paletas. Cada clic sobrescribe las variables de acento y reasigna el tono base de los blobs, manteniendo el offset aleatorio de cada uno para que no queden todos idénticos. Si Frutiger está activo, primero se sale de Frutiger para no mezclar los dos sistemas de fondo.
7.7 — Por qué los modos son excluyentes
Noche y Frutiger se manejan como un grupo excluyente: antes de activar uno se quitan las clases de los demás. "Cambiar color" es la excepción: no pertenece al grupo, es un ciclo independiente que puede convivir con cualquier modo salvo Frutiger.
Solo uno puede estar activo a la vez — comparte el mismo setMode() que el dock de arriba.
Server-side, sin sorpresas
Valida name, email (con FILTER_VALIDATE_EMAIL) y message en el propio PHP, repuebla los campos si hay errores, y llama a mail() en caso de éxito. Sus estilos usan las mismas variables del sitio, así que también reaccionan a los modos.
Un breakpoint, 900px
El nav de escritorio se oculta a favor de un menú móvil por debajo de 900px, y el dock de modos se achica: tooltips y texto de la pista se ocultan para no estorbar en pantallas chicas.
Los tres puntos de entrada
Modo nuevo: seguir el patrón de Frutiger —botón en el dock, clase en setMode(), reglas bajo body.mode-nombre.
Paleta nueva: un objeto más en el array palettes de modes.js.
Proyecto nuevo: un elemento más en $projects dentro de config.php.