Interfaz
Jerarquía clara y microinteracciones.
Front-end con estándares web. Código claro, animaciones fluidas y rendimiento primero.
<!doctype html>
<html lang="es">
<head>...</head>
<body>
<!-- ingeniería que se ve y se siente -->
Interfaz, rendimiento y seguridad. Diseño responsable con el usuario y la máquina.
Jerarquía clara y microinteracciones.
CSS y JS mínimos. Vitals en verde.
CSP, HSTS, HTTPS estricto.
Patrones en HTML, CSS y JS. Ejecuta la demo para verlos en acción.
<!-- Dialog accesible + foco -->
<button id="openDialog" class="btn">Abrir</button>
<dialog id="dlg" aria-labelledby="dlgTitle">
<h3 id="dlgTitle">Suscripción</h3>
<form method="dialog">
<input type="email" required placeholder="email" />
<menu>
<button value="cancel">Cancelar</button>
<button value="ok" class="btn">Guardar</button>
</menu>
</form>
</dialog>
<!-- Tabs semánticos -->
<div role="tablist" aria-label="Lenguajes">
<button role="tab" aria-controls="p-html" aria-selected="true">HTML</button>
<button role="tab" aria-controls="p-css">CSS</button>
</div>
/* Variables + contenedor + CQ */
:root{--space:12px}
.card{container-type:inline-size}
@container (min-width: 420px){ .card{ padding:24px } }
/* Tipografía fluida */
.title{ font-size:clamp(28px, 6vw, 56px) }
/* Animaciones eficientes */
.btn:hover{ transform: translateY(-2px) }
/* Accesibilidad: foco visible */
:focus-visible{outline:2px solid deepskyblue; outline-offset:3px}
// Dialog + debounce + lazy images
const dlg = document.getElementById('dlg');
const openBtn = document.getElementById('openDialog');
openBtn?.addEventListener('click', ()=> dlg.showModal());
// Debounce util
const debounce = (fn,ms=200)=>{ let t; return(...a)=>{ clearTimeout(t); t=setTimeout(()=>fn(...a),ms); } };
// Lazy load ejemplo
const io = new IntersectionObserver(es=>es.forEach(e=>{
if(e.isIntersecting){ const img=e.target; img.src=img.dataset.src; io.unobserve(img); }
}),{threshold:.1});
document.querySelectorAll('img[data-src]').forEach(i=>io.observe(i));
Etiquetas correctas, accesibilidad y SEO técnico. Menos divitis, más significado.
<header>, <main>, <nav>, <section>, <article>, <footer>.h1 por página. Jerarquía clara.aria-* coherente.<label for> y validación nativa.<article itemscope itemtype="https://schema.org/Article">
<h2 itemprop="headline">Guía rápida</h2>
<p itemprop="description">Resumen.</p>
</article>
Arquitectura escalable con variables, layout moderno y animaciones suaves.
clamp().transform y opacity para 60fps.:root{--gap:16px}
.stack{display:flex;flex-direction:column;gap:var(--gap)}
.cluster{display:flex;flex-wrap:wrap;gap:var(--gap);align-items:center}
DOM directo, módulos pequeños y eventos bien delimitados.
const q = (s,p=document)=>p.querySelector(s);
const acc = q('#faq-list');
acc.addEventListener('click', e=>{
const btn = e.target.closest('[data-acc]');
if(!btn) return;
const panel = document.getElementById(btn.getAttribute('aria-controls'));
const open = btn.getAttribute('aria-expanded') === 'true';
btn.setAttribute('aria-expanded', String(!open));
panel.hidden = open;
});
Prototipos y experimentos. Clic en una tarjeta para abrir el proyecto.
Detalles técnicos y procesos.
CSS crítico inline, precarga selectiva, imágenes responsivas, cacheo fuerte y JS diferido. Medición con Lighthouse y WebPageTest.
Headers estrictos (CSP, HSTS, X-Content-Type-Options), dependencias cero, validación y saneamiento del input.
Semántica correcta, contraste AA, navegación por teclado, roles ARIA y pruebas con lectores de pantalla.
¿Proyecto o colaboración? Escríbeme.