Joel Almeida - Editorial portfolio for a fashion and music photographer
A site I designed and built for Joel, a photographer and filmmaker who until then only had Instagram. Covers, editorials and live music told as a scroll story, with Astro, GSAP and Lenis and no UI framework in the browser.
Joel Almeida (@soyjoelalmeida) is a photographer and filmmaker. He shoots fashion editorials, magazine covers (Revista CARAS), backstage and live music (K4OS), works in Buenos Aires and Mendoza, and travels anywhere in Argentina. Until this site, his work lived on Instagram: a feed where a cover, a backstage shot and a concert sit side by side, with no order and no context. This is client work: I did the design and the development end to end.
What I built
A one-page portfolio. A hero slideshow of 8 photos, with a caption and a pause control. Below it, a scroll-driven story in 7 chapters - Caras, Live, Charlotte, Camila, Santiago, After Dark and Studio - and a work index with a List/Grid toggle. Dark and light theme, and the header hides when you scroll down so the photos keep the screen. The copy is in Spanish.
Design decisions
Swiss-minimal editorial, and the photos carry the page. One typeface, Archivo Variable, with the name set at weight 900 and width 125. One loud red moment: the name in the hero, and nothing else competes with it. Static grain, zero radius. The work is told in chapters instead of dumping a grid of thumbnails: each chapter is a shoot or a body of work, so a visitor reads a story before browsing.
Engineering decisions
A lightbox that opens out of the photo. Clicking a photo morphs it into the lightbox with the View Transitions API. When the browser doesn't support it, or the visitor prefers reduced motion, it falls back to a plain open.Back closes the overlay. The browser Back button closes the lightbox or the menu instead of leaving the page, which is what people press on a phone.Images. A sharp pipeline generates AVIF with a WebP fallback at widths 360, 640, 960 and 1280, so each device downloads the size it needs.No UI framework in the browser. Astro renders the page and the client only runs GSAP and Lenis (smooth scroll). Google Analytics (GA4) loads only after the page has loaded and the browser is idle.Security and delivery. A Content Security Policy with script hashes. The container is nginx-unprivileged running as non-root, with digest-pinned base images, deployed on Dokploy. The Archivo font is self-hosted. For search: JSON-LD (WebSite, Person, ImageGallery), a generated OG image, sitemap and robots.