ASTRO CSS PRINT PORTFOLIO 2025-11-12

Ingeniería de un CV Online: Más allá del PDF

Desarrollo de una identidad digital responsive con Astro, optimización para impresión (CSS Print) y accesibilidad WCAG 2.1.

El Desafío: Romper las Limitaciones del PDF Estático

Los currículums en PDF presentan una contradicción fundamental: son estáticos en un mundo profesional dinámico. No son indexables por buscadores, requieren descarga para visualización, y cada actualización implica redistribución manual. La solución moderna exige un CV web responsive que funcione como página interactiva y documento imprimible simultáneamente.

El desafío técnico consiste en crear una experiencia que mantenga perfección visual en A4 al imprimir, mientras ofrece navegación fluida en dispositivos móviles y escritorio. Esto requiere arquitectura dual: una para pantalla y otra para impresión.

Stack Técnico

La solución se construyó sobre tecnologías que priorizan performance y SEO:

  • Astro 5.16: Framework con arquitectura Islands que genera HTML estático, logrando cero JavaScript en cliente por defecto
  • Tailwind CSS 3.3: Sistema de utilidades para diseño responsive con configuración personalizada de colores y efectos glassmorphism
  • Vercel Edge Functions: Deployment con CDN global para tiempos de carga <100ms
  • Google Analytics 4: Tracking de interacciones sin comprometer performance

La ausencia deliberada de React/Vue reduce el bundle a <5KB de JS, maximizando Core Web Vitals.

Ingeniería de la Solución

Diseño Responsive vs. Print Perfect

El mayor desafío técnico fue garantizar que el diseño glassmorphism con degradados y efectos blur se tradujera correctamente a papel. La estrategia utiliza media queries print específicas:

/* Glassmorphism para pantalla */
.glass {
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

/* Conversión a bordes sólidos para impresión */
@media print {
  .glass {
    background: #ffffff;
    backdrop-filter: none;
    border: 1px solid #e5e7eb;
  }

  /* Forzar página A4 sin márgenes adicionales */
  @page {
    size: A4;
    margin: 15mm;
  }

  /* Evitar ruptura de secciones críticas */
  .no-break {
    page-break-inside: avoid;
  }

  /* Ocultar elementos interactivos */
  nav,
  .cta-buttons,
  footer {
    display: none !important;
  }
}

Este enfoque asegura que los degradados violeta-cian (#5706f3#24c1fb) se conviertan en bordes grises al imprimir, evitando desperdicio de tinta y mejorando legibilidad.

Arquitectura de Datos: Separación de Contenido

La arquitectura modular separa datos de presentación mediante componentes Astro reutilizables. El contenido se estructura en archivos .astro que actúan como fuente de verdad:

// src/data/experiencia.js
export const experienciaLaboral = [
  {
    puesto: "Asistente Contable",
    empresa: "Estudio MGAM",
    periodo: "2022 - Presente",
    responsabilidades: [
      "Conciliación bancaria y registro de operaciones diarias",
      "Preparación de reportes mensuales para análisis gerencial",
      "Gestión de facturación electrónica con AFIP",
    ],
    tecnologias: ["Excel", "Tango Gestión", "AFIP"],
  },
  {
    puesto: "Freelance - Marketing Digital",
    empresa: "LeoMartinK Studios",
    periodo: "2020 - Presente",
    responsabilidades: [
      "Desarrollo de sitios web con Astro y WordPress",
      "Implementación de estrategias SEO y Google Analytics",
      "Diseño de identidad visual y brand books",
    ],
    tecnologias: ["Astro", "WordPress", "Tailwind CSS", "Google Ads"],
  },
];

Los componentes Astro consumen estos datos mediante importación directa:

---
// src/components/sections/Experiencia.astro
import { experienciaLaboral } from '@/data/experiencia.js';
---

<section id="experiencia" class="py-20 bg-bg-secondary">
  <div class="max-w-6xl mx-auto px-4">
    <h2 class="text-4xl font-bold mb-12">Experiencia Laboral</h2>

    {experienciaLaboral.map((trabajo) => (
      <article class="glass p-6 rounded-lg mb-6 no-break">
        <h3 class="text-2xl font-bold text-blue-400">{trabajo.puesto}</h3>
        <p class="text-muted">{trabajo.empresa} | {trabajo.periodo}</p>

        <ul class="mt-4 space-y-2">
          {trabajo.responsabilidades.map((tarea) => (
            <li class="text-muted">• {tarea}</li>
          ))}
        </ul>

        <div class="flex gap-2 mt-4">
          {trabajo.tecnologias.map((tech) => (
            <span class="px-3 py-1 rounded-full bg-blue-500/20 border border-blue-500/50 text-sm">
              {tech}
            </span>
          ))}
        </div>
      </article>
    ))}
  </div>
</section>

Esta separación permite actualizar experiencias editando un solo archivo JavaScript sin tocar HTML, facilitando mantenimiento a largo plazo.

Accesibilidad: HTML Semántico y ARIA

El proyecto implementa WCAG 2.1 Level AA mediante estructura semántica:

<main role="main" aria-label="Curriculum Vitae de Leonardo Galeano">
  <section aria-labelledby="hero-heading">
    <h1 id="hero-heading">Leonardo Galeano</h1>
    <p>Asistente Contable & Marketing Digital</p>
  </section>

  <nav aria-label="Navegación principal" class="fixed top-0 z-50">
    <ul role="menubar">
      <li role="none">
        <a href="#experiencia" role="menuitem" aria-current="page">
          Experiencia
        </a>
      </li>
    </ul>
  </nav>

  <article class="glass" aria-label="Proyecto destacado">
    <h3>Consultoría de Branding</h3>
    <a href="/proyecto" aria-label="Ver caso de estudio completo">
      Ver Caso de Estudio →
    </a>
  </article>
</main>

Los puntos clave incluyen:

  • Landmarks ARIA (role="main", aria-label) para navegación por lectores de pantalla
  • Contraste mínimo 4.5:1 entre texto y fondos (verificado con Lighthouse)
  • Focus visible con anillos azules (focus:ring-2 ring-blue-400) en elementos interactivos
  • Orden lógico de headings (h1 → h2 → h3) sin saltos

Conclusión: Performance y Escalabilidad

El resultado final alcanza Lighthouse Score 100/100 en las cuatro métricas:

  • Performance: 100 (FCP <0.8s, LCP <1.2s)
  • Accessibility: 100 (navegación por teclado, contraste óptimo)
  • Best Practices: 100 (HTTPS, sin errores de consola)
  • SEO: 100 (meta tags, sitemap.xml, robots.txt)

La arquitectura modular permite escalar agregando nuevas secciones sin refactorización. El patrón de separación contenido/presentación facilita traducciones futuras mediante archivos experiencia.es.js / experiencia.en.js.

El tiempo de build en Vercel es <30 segundos, con invalidación de caché automática ante commits. El CV impreso mantiene fidelidad visual 1:1 con la versión digital.


Repositorio Showcase: github.com/LeoMartinK/cv-engine-showcase
Demo en vivo: cv-leogaleano.vercel.app