Film Portfolio Build
Built a 31-project film portfolio on Next.js 15 with hover previews, autoplay flows, Cloudinary hosting, and a minimal A24-ish aesthetic — plus a bunch of real-world breakage fixes.
What we built
A Next.js 15 film portfolio with 31 video projects.
Full-screen video hero + parallax-ish work sections.
Hover-preview video cards in a responsive grid.
Autoplay behavior on click, with platform-safe fallbacks.
Cloudinary video hosting with dynamic poster extraction.
Light/dark theme + scroll-responsive header.
Minimalist aesthetic influenced by A24 (typography + whitespace doing the work).
What broke and how we fixed it
1) Work section ‘leaked’ into the hero: `min-h` left a gap where the next section peeked through. Fix: use `h-screen` for true 100vh coverage.
2) Mobile header got cut off: desktop padding was too big. Fix: responsive padding/text, hide non-critical header content on mobile, reduce gaps.
3) Next.js 15 client component params caused 404s: `params` is a Promise. Fix: server can `await`, client must `use(params)`.
4) Mobile auto-fullscreen failed: iOS blocks fullscreen requests without direct user gesture. Fix: device detection + desktop-only fullscreen, always allow play.
5) Cloudinary asset naming chaos: random suffixes meant filenames weren’t predictable. Fix: pull asset list via Cloudinary API and map manually (reliable, tedious).
6) Bad poster frames: first frame often black/blurry. Fix: use Cloudinary frame extraction (`so_X`) to pick better frames without re-uploading.
7) Header overlapped detail page content: fixed header + top-starting content caused collisions. Fix: simplify the detail page UI and avoid duplicating header navigation.
8) Year removed from UI but still needed: almost deleted it from the data model. Fix: hide in UI, keep in data for future filtering/sorting.
New challenges and patterns that worked
Compression pipeline: raw videos were too big. Built an FFmpeg flow for preview loops and compressed 1080p full versions (big size cuts with no visible quality loss).
Priority ordering: client wanted featured projects first. Chose manual array order (curation beats sorting logic for small datasets).
Autoplay URL flag: used `?autoplay=true` to differentiate click-through vs direct navigation (better UX and shareable URLs).
Header state machine: combined Intersection Observer (hero in view) + scroll direction tracking (hide on scroll down).
Hover preview without fighting autoplay policies: muted autoplay runs; CSS opacity reveals on hover (smoother than JS play/pause spam).
Fluid type: used `clamp()` for typography that scales smoothly instead of breakpoint jumps.
Theme switching without re-renders: CSS variables + `data-theme` attribute for instant updates.
Summary
Built: 31-project video portfolio with autoplay flows, hover previews, responsive layout, theme switching.
Broke: hero gaps, mobile header sizing, Next.js 15 params, fullscreen policies, asset management, posters, header overlap, UI vs data confusion.
Fixed: all of it with better patterns: full viewport sections, responsive sizing, `use()` for params in client components, device-safe fallbacks, tooling, transformations, minimal UI, data preservation.
Key lesson: test on real devices, have fallbacks for everything, and keep the design simple so the work stays loud.
← Back to Notes