Files
twotalesanimation 6c464d6dfb Add real studio content: Festo F1 film, filmography, service stills
From the Dec 2024 company profile: Pretoria location, founding year, service
list with stills, and 14 film/series credits with posters. Festo F1 spot
transcoded for web (cropped letterbox, 14 MB, faststart).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 18:40:45 +02:00

38 lines
1.8 KiB
TypeScript

import type { Project } from "@/content/site";
// A project still. Uses the project image when present, otherwise renders a
// stylised "viewer" frame (gradient plate + safe-area guide + slate overlay).
export default function Frame({ project, priority = false }: { project: Project; priority?: boolean }) {
const h = project.hue;
return (
<div className="relative aspect-[2.39/1] w-full overflow-hidden bg-ink-2">
{project.image ? (
// eslint-disable-next-line @next/next/no-img-element
<img
src={project.image}
alt={project.title}
loading={priority ? "eager" : "lazy"}
className="absolute inset-0 h-full w-full object-cover transition-transform duration-[1.2s] ease-out group-hover:scale-[1.04]"
/>
) : (
<div
className="absolute inset-0 transition-transform duration-[1.2s] ease-out group-hover:scale-[1.06]"
style={{
background: `radial-gradient(ellipse 60% 80% at 70% 60%, hsl(${h} 70% 45% / .55), transparent 70%),
radial-gradient(ellipse 50% 60% at 20% 30%, hsl(${(h + 40) % 360} 60% 30% / .5), transparent 70%),
linear-gradient(180deg, hsl(${h} 25% 9%), hsl(${h} 30% 4%))`,
}}
/>
)}
<div className="pointer-events-none absolute inset-x-0 top-0 h-1/3 bg-gradient-to-b from-black/50 to-transparent" />
<div className="pointer-events-none absolute inset-[6%] border border-white/10" />
<div className="pointer-events-none absolute top-3 left-4 font-mono text-[10px] tracking-widest text-white/60 uppercase">
{project.category} · {project.year}
</div>
<div className="pointer-events-none absolute top-3 right-4 font-mono text-[10px] tracking-widest text-white/60 uppercase">
{project.video ? "▶ Film" : "Still"}
</div>
</div>
);
}